volatile의 경우 어떤 의미에서는 앞에서 설명한 컴파일러의 최적화와 관계있습니다. 그 외에도 CPU 내, 외부의 캐쉬와 갈은 하드웨어적인 최적화와도 관계가 있습니다.
volatile 키워드가 가장 많이 사용되는 경우의 하나가 memory-mapped I/O인 경우입니다. 메모리의 특정 영역을 특정 장치와 연결하여 사용하는 방법입니다. 가장 흔한 예가 비디오 메모리가 되겠고, 그 이외에도 많은 장치들을 이러한 식으로 사용될 수 있습니다.즉, 자신 엄밀하게 말한다면 컴파일러가 컴파일하고 있는 코드의 상황과는 관계 없이 바뀔 수 있는 메모리 변수가 있다면, 해당 변수에 대해 특별한 최적화를 하지 못하도록 컴파일러를 제약하는 키워드가 volatile입니다.
예를 들어, 0x0C000000 번지에 특별한 장치가 있다고 하겠습니다. 이 장치가 일종의 센서라고 하고 입력되는 센서값의 범위에 따라 다른 동작을 수행하게 프로그래밍을 아래와 같이 하였다고 하면,int *p = 0x0C000000;
while (1) {
if (*p == 0) {
break;
} else if (*p < lower_limit) {
action 1;
} else if (*p < upper_limit) {
action 2;
}
wait 10 mili-seconds
}
똑똑한 컴파일러는 위의 코드를 아래와 아래와 같이 바꿉니다.
int *p = 0x0C000000;
register int pvar = *p;
if (pvar == 0) {
} else if (pvar < lower_limit) {
while (1) {
action 1;
wait 10 mili-seconds;
}
} else if (pvar < upper_limit) {
while (1) {
action 2;
wait 10 mili-seconds;
}
}
위와 같이 코드가 변형된다면, 프로그래머가 의도한 바와는 다른 결과가 나타나게 됩니다. 이러한 최적화를 억제하는 목적으로 volatile을 사용합니다. 컴파일러는 volatile 키워드가 선언된 변수에 대해서는 무조건 메모리에 접근하여 됩니다. 이러한 memory-mapped I/O 이외에도, 쓰레드 등으로 프로그램을 만들어서 공유변수를 한쪽에서 읽고, 한쪽에서 쓰는 경우도 해당될 수 있으며, 시스템 시간과 같이 특정 위치의 변수값이 자신과는 독립적으로 계속 변하는 경우에도 사용할 수 있습니다.
Powered by ScribeFire.
댓글 없음:
댓글 쓰기