[C언어] Volatile 변수란?
[C언어] Volatile 변수란?

붤러타일? 발음하기 힘들다....


Volatile 변수

기본적으로 C/C++ 컴파일러는 최적화의 기능을 가지고 있습니다. 비효율적이거나 불필요한 연산은 생략하고 코드를 최적화 시킵니다.

변수를 선언할 때 앞에 volatile을 붙이면 컴파일러는 해당 변수를 최적화에서 제외하여 항상 메모리에 접근하도록 만듭니다.



사용 방법

  • 기본적인 변수 사용 int a, static int a
  • Volatile 변수 사용 volatile int a ,static volatile int a



사용하는 이유

  1. 컴파일러에서 최적화를 방지한다.
  2. 후속 프로그램이 변수를 다룰때 레지스터가 아닌 메모리에서 읽어오도록 한다. (임베디드일 경우)
  3. 만약 16비트 마이크로 먼트롤러에서 32비트(int, long) 변수를 읽어오려면 두번에 걸쳐서 메모리를 읽어야 한다. 그 변수를 읽는 동안에 갑자기 값이 바뀔 수 있는데 읽히는 동안 비트를 못건드리게 해야한다.




코드

프로그래머의 의도와는 다르게 컴파일러가 최적화를 진행할 수 있다. 또한 임베디드 환경이라면 상황이 다를 수 있다.


C 소스코드

int main()
{
  int i = 0;

  while (i < 10)
      i++;

  printf("%d\n", i);
}

위와 같이 작성된 코드는 컴파일러의 최적화로 인해 어셈블리어로 아래와 같은 구조로 진행한다.

int main()
{
  int i = 10;    // while문 제거하고 10을 할당

  printf("%d\n", i);
}



임베디드 소스코드

static int power;

void Power_ON_OFF()
{
    power = 0;

    while(power!=1);    
}

위와 같은 코드는 아래와 같이 무한루프로 최적화 된다.

void Power_ON_OFF()
{
    power = 0;

    while(true);    
}

하지만 만약에 power변수가 인터럽트 또는 하드웨어 장치의 레지스터라면 다른 동작에 의해 값이 변경될 수 있다.



비주얼 스튜디오 테스트 (Release 모드)

  • 아래의 소스코드를 VC++에서 돌려보면 동작시간이 대략 0.001초정도 된다.
  • 입력이 10만이고 시간복잡도는 O(N^2)이라서 최소 10초가 넘어야하지만 0.001초가 걸린다?
  • k++연산이 어느정도 예상되다보니 컴파일러에서 연산을 제외하고 최적화 진행.
    (일반적으로 알고리즘 문제를 풀때는 1억에 1초로 생각합니다.)
    (개인 컴퓨터는 처리속도가 빠르기 때문에 대략 10억에 1초 정도 걸립니다.)
#include <stdio.h>
#include <vector>
#include <time.h>

using namespace std;

int start, end_t;
int k;                         //이 부분을 volatile int k로 선언시에 대략 10초 소요.
//volatile int k;         //최적화 제외 변수
int main()
{

  start = clock();     //1클럭 = 1ms

	for (int i = 0; i < 100000; i++)
		k++;




	for (int i = 0; i < 100000; i++)
	{
		int j;
		for (j = i + 1; j < 100000; j++)
		{
			k++;
		}
	}

	end_t = clock();



	printf("%.4fsec ", (double)(end_t - start)/1000);

	return 0;
}

정확한 시간복잡도 계산값은 N + ( ( N * (N-1) ) / 2 ) 입니다.