C/C++ 프로그래밍 언어에서 이 키워드는 최적화 등 컴파일러의 재량을 제한하는 역할을 한다. 개발자가 설정한 개념을 구현하기 위해 코딩된 프로그램을 온전히 컴파일되도록 한다. 주로 최적화와 관련하여 volatile가 선언된 변수는 최적화에서 제외된다.[위키백과]
=> 즉, 컴파일러에서 최적화 하는 것을 막아버린다는건데, 아래의 예시로 설명하겠다.
int num1;
num1 = 1; // 컴파일러 최적화로 인한 삭제
num1 = 2; // 컴파일러 최적화로 인한 삭제
num1 = 3;
=> 위의 코드에서, 의미없이 num1변수를 재정의 하기 때문에, 컴파일러는 1,2의 작업을 삭제하는 최적화를 진행한다.
=> 그러나, 이것이 멀티쓰레드거나, 하드웨어 참조 코드여서 전부 적용시켜야 한다면, 위의 코드는 최적화되어선 안된다.
=> 그럴때 사용하는것이 volatile
volatile int num1;
num1 = 1;
num1 = 2;
num1 = 3;
=> volatile을 넣게 되면, 1,2의 작업이 최적화되지않고, 모두 실행하게 된다.
사용처
=> 1. Multi thread
=> volatile을 쓰지 않으면 최적화로 인해서 i=0과 i=1이 정상작동하지 않지만, volatile을 통해 최적화를 막아줌으로써 정상작동
#include<thread>
#include<iostream>
#include<chrono>
using namespace std;
volatile int i;
void Func1()
{
int count = 0;
extern volatile int i;
i = 0;
while (1)
{
if (1 == i)
cout << "Count : " << ++count << endl;
}
}
void Func2()
{
extern volatile int i;
i = 0;
while (1)
{
chrono::seconds sleepSec(1);
this_thread::sleep_for(sleepSec);
i = !i;
}
}
int main()
{
thread t1(Func1);
thread t2(Func2);
t1.join();
t2.join();
return 0;
}
=> 2. Interrupt
int pin = 13;
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE);
}
void loop()
{
digitalWrite(pin, state);
}
void blink()
{
state = !state;
}
출처: https://www.arduino.cc/en/Reference/Volatile
=> 3. Memory-mapped I/O
입출려 장치 제어 코드
*(unsigned int*)A = 0x2011;
*(unsigned int*)A = 0x2012;
*(unsigned int*)A = 0x2013;
*(unsigned int*)A = 0x2014;
*(unsigned int*)A = 0x2015; // 이것만 실행
///////////////////////////////////////
*(volatile unsigned int*)A = 0x2011; // 실행1
*(volatile unsigned int*)A = 0x2012; // 실행2
*(volatile unsigned int*)A = 0x2013; // 실행3
*(volatile unsigned int*)A = 0x2014; // 실행4
*(volatile unsigned int*)A = 0x2015; // 실행5
'C++ > Tips' 카테고리의 다른 글
[c++]SmartPointer (0) | 2021.02.02 |
---|---|
[c++] struct (0) | 2021.01.26 |
[c++]Typename (0) | 2021.01.26 |
[c++]auto (0) | 2021.01.19 |
[C++] Extern (0) | 2021.01.05 |