1. 변수가 함수 내에서만 사용될 때는 지역변수로 전환Global 변수는 일반적으로 메모리를 차지하도록 컴파일된다.
그러나 지역변수로 정의해서 임시로 사용하게 되면 레지스터를 사용하도록 최적화가 가능하다.
그럼 연산도 빨라지고 메모리 사용도 줄일 수 있다.
2. inline함수의 static 화inline 함수, 또는 일반 함수인데 간단해서 컴파일러가 자동 최적화로 inline화 하는 함수가,
만일 해당 모듈에서만 사용되고 외부에 공개될 일이 없다면, static을 정의해 주는 것이 좋다.
static을 정의하지 않으면, 외부에서 불리는 경우를 고려하여 컴파일러가 함수 구현체를 Code 부에 남겨둔다.
static을 정의하면, 해당 모듈(c파일)에서 해당 호출부를 inline 대체한 후, 실제 구현체를 Code 부에서 삭제한다.
3. LookUp Table의 사용컴퓨터와 가위바위보를 하여 결과를 리턴하는 함수를 만든다고 해 보자.
컴퓨터(cpu)와 나(me)의 가위바위보 값을 int로(가위=0, 바위=1, 보=2) 구현한다고 했을 때,
if else나 switch로 구현하게 되면 매우 비효율적인 코드가 된다.
우리는 이미 가위바위보에 대해 결과를 알고 있다. 이를 LookUp Table로 만들어두고, 인덱싱으로 결과를 가져오기만 하면 된다.
int compare(int cpu, int me) {
const static int resultarray[3][3] = {{0, 1, -1}, {-1, 0, 1}, {1, -1, 0}};
return resultarray[cpu][me];
}
|
LookUp Table중에 아래와 같이 처리하는 경우도 있다.
sin(), cos(), tan() 같이 미리 결과값을 알고 있는 Floating 연산에 대해서, PC등 FPU 지원 프로세서는 일반 Library를 사용해도 되지만
미지원 프로세서는 성능이 2~40배 떨어지는 경우가 있다. 이 때, 결과에 대한 LookUp Table을 만들어서 별도 Library를 사용하면
빠르게 결과를 가져올 수 있다.
4. LookUp Table의 const화부팅 이미지나 많은 초기 설정값들 같이 큰 배열을 Global이나 Local Static 변수로 선언하는 경우가 있다.
이 때 const를 붙이면, 임베디드 XIP 구조에서는 rodata로 포함되면서 ROM -> RAM Copy가 일어나지 않아 최적화가 가능하다.
추가로, Local 변수인 경우 static + const를 함께 정의해 주는 것이 좋다.
5. index 비교문 최적화
parameter로 index 값을 받아서 배열이나 특정 주소를 접근하는 함수들을 구현하는 경우가 있다.
이 때, index 범위를 보통 0부터 MAX까지 확인하는 경우가 많은데,
아래 왼쪽 코드보다는 오른쪽 최적화 코드가 Compare 횟수가 더 적게 컴파일된다.
non 최적화 |
최적화 |
int func(int i) {
if (i < 0 || i > 4) {
printf("Index Error!\n");
return -1;
}
return array[i];
}
|
int func(int i) {
if ((unsigned int)i > 4) {
printf("Index Error!\n");
return -1;
}
return array[i];
}
|