'optimization'에 해당되는 글 1건
volatile 은 언제 사용 해야 하나 - 2009/02/09 16:31
결론부터 이야기 하자면 volatile은 (1)메모리맵 방식의 주변장치 레지스터, (2)멀티스레드 환경의 공유변수, 그리고 (3)인터럽스 서비스루틴 내에서 사용되고 있는 전역변수의 경우 사용 해야 한다.
해당 자원을 volatile 으로 선언하지 않은 상황에서 컴파일러 최적화 작업을 수행 하였을 시 코드는 예상치 못한 동작을 일으킬 가능성이 상시 존재한다.
그 이유는 컴파일러는 포인터(Pointer)가 가리키는 곳은 항상 메모리로 생각하는 데서 문제가 발생한다. 다음은 그 예를 보인다.
소스의 예
unsigned long* reg = (unsigned long*)0xFE000000; int main(void) { while (*reg == 0); return(0); } |
테스트는 ADS(ARM Developers Suite)에서 실행하였으며 각 해당 코드의 역어셈블(DISASSEMBLE) 내용을 보인다.
실험1 : -O0(옵티마이제이션 끔)
^ 이는 정상적인 작동이 예상된다. 레지스터 주소의 값을 루프를 돌면서 반복적으로 읽어낸다.
실험2 : -O2(옵티마이제이션 켬)
^ 최적화 설정시 코드는 해당 레지스터 주소에서 해당값을 한번만 읽어내고 공루프(endless loop)를 회전한다. 이는 프로그래머가 의도했던 것은 분명 아니다.
실험3: -O2(옵티마이제이션 켬. 그리고 volatile 사용)
소스에 약간의 수정을 가하여 다음과 같이 더불어 실행한 결과를 보인다.
volatile unsigned long* reg = (unsigned long*)0xFE000000; int main(void) { while (*reg == 0); return(0); } |
^의도한 대로 코드는 최적화 설정시에도 잘 동작할 것이다.
자! 정리해 보자. 해당 적절한 위치에 volatile 을 선언해 주고 더하여 컴파일 최적화 옵션도 켠 상태에서 만약 초기개발을 진행한다면 이는 사후 발생 할 지도 모르는 심각한 오류를 예방 하는 것이 될 수 있을 것으로 생각된다.
-홍익컴닷컴-
http://www.hongikcom.com
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요->





