Embedded

[C언어] [컴파일러] [Embedded] 최적화와 오류에 대해

Teodore 2023. 1. 11. 21:44
728x90

오늘은 Embedded환경에서 컴파일러의 역할과 최적화 오류에 대해 적어보려고 한다. 

 

많은 Embedded 개발자가 항상 고민하는 부분은 메모리 사용량과 최적화, 시스템 속도 등일 것이다.

물론 최근에는 메모리 가격이 정말 많이 내려가서 메모리를 고려하지 않고도 Embedded Firmare를 만드는데 문제가 없긴 하다. 

그래도 알아두어서 나쁠것은 없으니 한번 알아보도록 하자. 

 

일반적으로 메모리를 많이 사용하면 속도를 올릴 수 있고, 메모리를 최적화 하려면 일부 속도를 포기해야 한다. 

두개의 관계를 Trade-off 관계로 어느 것을 중점적으로 최적화 해야 할지 고민해야 하는 부분이다. 

1. 개발자의 최적화 기법

개발자가 직접 최적화 코드를 고민하여 넣는 방법이다. 

변수의 범위를 예측하여 최적화된 타입으로 선언하는 기법은 기본

함수의 호출 빈도에 따른 inline 사용

반복 루프의 언롤링 기법

*/ 연산자 대신 << >> 쉬프트 연산자 사용 또는 비트 연산

위의 기법들을 많이 배웠고 또 아직 사용하고 있을 것이다. 

결론부터 말하면 모두 쓸데 없으니 쓰지 않는 것이 좋다. 

 

그 이유는 요즘 나오는 대부분의 컴파일러는 우리가 알고 있는 것 이상의 최적화 기법을 모두 적용시켜 준다. 

그래서 개발시작부터 끝까지 항상 최적화 레벨을 최대로 놓고 시작하길 권한다.

visual studio를 사용하여 개발하는 경우 debug모드에서는 문제가 없었는데 release만 하면 동작하지 않는 경우가 발생한다. 이것은 컴파일러 최적화 오류다.

2. 컴파일러 최적화 오류

컴파일러의 최적화 레벨을 최대로 놓고 프로그래밍 하는 경우에 개발자가 의도하지 않은 상태로 동작하는 경우가 있다. 

예를 들어 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(void){
 
  int i= 0;
  int val;
 
  val = get_adc();
  printf("adc val : %d\n", val);
  // delay
  for(i = 0; i < 1000000; i++);
  val = get_adc();
  printf("adc val : %d\n", val);
 
  return 0;
}
cs

위 코드에서 의도한 것은 adc값을 일정 시간 간격으로 2번 읽어 보는 것으로 값의 차이를 보려고 하는 것이다. 

그러나 컴파일러는 위의 코드 중 delay를 위한 for문을 미리 계산하여  i의 값을 1000000으로 변경해놓고 프로그램을 진행한다. 

과도한 최적화가 사용자의 의도를 제대로 해석하지 못하는 이런 케이스의 경우에는 

반드시 volatile을 붙여줘야 한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(void){
 
  volatile int i= 0;
  int val;
 
  val = get_adc();
  printf("adc val : %d\n", val);
  // delay
  for(i = 0; i < 1000000; i++);
  val = get_adc();
  printf("adc val : %d\n", val);
 
  return 0;
}
cs

 

오늘의 결론은 개발자는 컴파일러의 최적화 레벨을 최대로 올려놓고 개발을 시작하고

코드는 클린코드 기법을 참조하여 최대한 가독성을 높여 개발하라는 것이다. 

그럼 오늘도 좋은 하루 되길

728x90

'Embedded' 카테고리의 다른 글

[C 언어] [Embedded] 메모리 동적 할당에 대해 (2)  (0) 2023.01.19
[C 언어] [Embedded] 메모리 동적 할당에 대해 (1)  (0) 2023.01.17
[C 언어] [Embedded] Endian mode  (0) 2023.01.14
방향  (0) 2023.01.07
Embedded  (0) 2023.01.06