Posts

Showing posts with the label C코드 최적화

C코드 최적화 - 전역변수 대신 지역변수 사용

반복문 등에서 반복적으로 사용되는 변수 등은 전역변수 말고 지연변수를 사용하는 게 빠르다. 지역변수는 CPU 레지스터에서 바로 사용되나, 전역변수는 RAM에서 레지스터로 읽어와서 결과를 쓰기 때문이다. 『 레지스터 32bit CPU인 경우에, CPU에는 여러 연산(더하기, 빼기 등)을 처리할 수 있는 연산기가 있고, 내부에는 32bit 레지스터(register)가 여러 개 있다. 레지스터는 CPU가 사용하는 조그마한 저장 공간이다. CPU는 레지스터 저장공간을 사용해서 연산을 한다. 예컨대, c = a + b; 라면 CPU는 a, b를 각각 레지스터0, 레지스터1에 올려 놓고 더하기 연산을 해서 레지스터2에 더하기 결과를 넣을 수 있다. 』 int global_sum = 0; int calculate_sum_by_global_variable(void) { for (int i = 0; i < 10; i++) { global_sum += get_some_value(i); } } void calculate_sum_by_local_variable(void) { int local_sum = 0; for (int i = 0; i < 10; i++) { local_sum += get_some_value(i); } global_sum = local_sum; } 위의 C코드 예제를 보면 지연변수를 사용하는 게 더 느릴 거라고 생각할 수도 있다. C코드상으로는,  전역변수 사용 시에는 전역변수에 바로 합계를 계산하는 반면에,  지역변수를 사용 시에는 지역변수를 선언하고 합계를 계산한 후에 전역변수에 대입하기 때문이다. 하지만 CPU가 동작할 때는, 지역변수 사용 시에는 [①레지스터에 할당된 지역변수에 더하기]를 10번 한 후에 [②전역 변수(RAM)에 대입]하는 반면에, 전역변수 사용 시에는 [①전역변수를 RAM에서 읽어서 레지스터에 넣고 ②더하기를 한 후에...

C코드 최적화 - char, short 대신 int 사용

0~100의 값만 필요한 변수라면 성능 관점에서 char, short, int 중에 어느 걸 써야 할까? int를 써야 한다. int 대신에 char, short 을 사용하면 성능이 떨어지는 경우가 있기 때문이다. 먼저 CPU 동작을 매우 간단하게만 알아보자. 32bit CPU인 경우에, CPU에는 여러 연산(더하기, 빼기 등)을 처리할 수 있는 연산기가 있고, 내부에는 32bit 레지스터(register)가 여러 개 있다. 레지스터는 CPU가 사용하는 조그마한 저장 공간이다. CPU는 레지스터 저장공간을 사용해서 연산을 한다. 예컨대, c = a + b; 라면 CPU는 a, b를 각각 레지스터0, 레지스터1에 올려 놓고 더하기 연산을 해서 레지스터2에 더하기 결과를 넣을 수 있다. 그런데, 32bit인 int는 레지스터에 그대로 넣으면 되는데, 8bit인 char, 16bit인 short은 레지스터에 어떻게 넣을까? 부호 있는 수(signed)이면 부호확장(sign extension)하고 부호 없는 수(unsigned)이면 제로확장(zero extension)해서 레지스터에 넣는다. 포스팅 ▶ 부호 확장(sign extension)과 제로 확장(zero extension) int 대비 그만큼 추가 연산이 발생해서 성능에 불이익이 생긴다. (CPU마다 명령어(instruction)가 다르므로 추가 연산이 없는 CPU도 있을 수도 있지만 일반적으로는 추가 연산이 발생한다.) 아래에서 추가 연산이 발생하는 C코드를 보자. unsigned char increase_char(unsigned char param) { param = param + 1; // param = param + 1; // param = param & 0x000000ff; return param; } unsigned short increase_short(unsigned short param) { param = param + 1; // pa...