본문 바로가기
프로그래밍 언어/C++

[C/C++] Volatile 키워드

by 까망 하르방 2024. 12. 23.
반응형

volatile 키워드란?

• 컴파일러 최적화(optimization)에서 제외한다.

• 레지스터에 값을 사용하지 않고 항상 메모리에 접근 참조

• 명확한 표준이 없어 컴파일러마다 차이가 있긴 하다.

 

 

volatile 필요성

C/C++ 컴파일러는 다양하며 최적화도 계속 좋아지고 있다.
예를 들어, 반복문을 변경하거나 실행 순서를 변경하기도 한다.
코드 최적화 개발자 목적과 다르게 동작하기도 해서 주의해야 한다.

 

예제

volatile 적용하지 않은 경우

// case 1)
*(unsigned int *)0x8C0F = 0x1;
*(unsigned int *)0x8C0F = 0x2;
*(unsigned int *)0x8C0F = 0x3;
*(unsigned int *)0x8C0F = 0x4;
*(unsigned int *)0x8C0F = 0x5;

// case 2)
void foo(char *buf, int size){
    char *p = (volatile char*)0x123;
    for(int i=0; i<size; i++)
    {
        buf[i] = *p;
    }
}

 

case 1)에서

"0x8C0F" 주소에서 5번 메모리 쓰기를 하고 있다.

같은 주소에 처리되 있는데 컴파일러는 최적화해서

제일 마지막 동작만 수행할 수 있다.

 

case 2) 에서도

char *p는 실제 주소(0x123)에 매번 접근하지 않고

한번 읽어와서 반복해서 사용할 수도 있다.

 

하지만 실제 동작을 위해서는 0x1 → 0x2 → ... → 0x5

모두 필요한 동작일 수 있다.

 

 

예제

volatile 적용한 경우

// case 1
*(volatile unsigned int *)0x8C0F = 0x1;
*(volatile unsigned int *)0x8C0F = 0x2;
*(volatile unsigned int *)0x8C0F = 0x3;
*(volatile unsigned int *)0x8C0F = 0x4;
*(volatile unsigned int *)0x8C0F = 0x5;

// case 2
void foo(char *buf, int size){
    volatile char *p = (volatile char*)0x123;
    for(int i=0; i<size; i++)
    {
        buf[i] = *p;
    }
}

 

 

volatile 키워드는 크게 3가지 경우에 많이 사용된다.

(1) Memory-mapped I/O

(2) 인터럽트 서비스 루틴(Interrupt Service Routine)

(3) 멀티 쓰레드 환경

반응형

댓글