c 코드 최적화

1.      중요 한 80 - 20 룰.
경험 에 의 해 확 정 된 80 - 20 규칙 을 잊 지 마 세 요. 전형 적 인 프로그램 이 80% 의 시간 으로 20% 의 코드 를 집행 한다 고 주장 합 니 다.
이것 은 소프트웨어 개발 자로 서 프로그램의 성능 을 전면적으로 향상 시 킬 수 있 는 20% 의 코드 를 식별 하 는 것 이 목표 라 는 것 을 일 깨 워 주기 때문에 중요 한 규칙 이다.
너 는 각종 방식 으로 무기한 으로 너의 함 수 를 최적화 할 수 있 지만, 네가 정확 한 함수 에 정력 을 집중 하지 않 으 면 헛되이 정력 을 낭비 하 는 것 이다.
2.      배열 색인 대신 포인터 연산
이렇게 하면 종종 빠 르 고 짧 은 코드 가 생 길 수 있다.배열 색인 에 비해 포인터 가 코드 속 도 를 빠르게 하고 공간 을 적 게 차지 합 니 다.다 차원 배열 을 사용 할 때 차이 가 더욱 뚜렷 하 다.아래 의 코드 작용 은 같 지만 효율 은 다르다.
    
for(;;){
	a = array[t++];
	……
}

 
    
p = array;
for(;;){
	a = *(p++);
	……
}

 
포인터 방법의 장점 은 array 의 주 소 는 주소 p 를 불 러 올 때마다 순환 할 때마다 p 증분 작업 만 하면 된다 는 것 이다.배열 색인 방법 에서 매번 순환 할 때마다 t 값 에 따라 배열 아래 표 시 된 복잡 한 연산 을 구 해 야 합 니 다.
3.      체크 리스트 (게임 프로그래머 필수 과목)
똑똑 한 게임 인 대 새 우 는 기본적으로 자신의 주 순환 에서 무슨 연산 작업 을 하지 않 는 다. 절대로 먼저 계산 을 다 한 다음 에 순환 에서 표를 찾 는 것 이다.아래 의 예 를 보십시오.
이전 코드:
long factorial(int i) 
{ 
    if (i == 0) 
   return 1; 
else 
   return i * factorial(i - 1); 
}

새 코드:
static long factorial_table[] = {1, 1, 2, 6, 24, 120, 720  /* etc */ }; 
long factorial(int i) 
{ 
return factorial_table[i]; 
}

표 가 크 고 쓰기 어 려 우 면 init 함 수 를 써 서 순환 외 에 임시로 표를 만 듭 니 다.
4.      구조 체 구성원 의 배치
긴 종 류 를 짧 은 앞 에 두 면 메모리 의 구멍 을 피 할 수 있 습 니 다.
5.      순환 성능 향상
순환 의 성능 을 향상 시 키 려 면 불필요 한 상수 계산 을 줄 이 는 것 이 매우 유용 하 다 (예 를 들 어 순환 에 따라 변화 하지 않 는 계산).
6.      인 라인 함수
C + + 에서 키워드 인 라인 은 모든 함수 의 성명 에 추가 할 수 있 습 니 다.이 키 워드 는 컴 파일 러 에 게 함수 내부 의 코드 로 지 적 된 함수 에 대한 모든 호출 을 교체 해 달라 고 요청 합 니 다.이렇게 하면 두 가지 측면 에서 함수 호출 보다 빠르다. 첫째, 호출 명령 에 필요 한 실행 시간 을 절약 했다.둘째, 변 원 과 전달 과정 에 필요 한 시간 을 절약 했다.그러나 이런 방법 을 사용 하면 프로그램의 속 도 를 최적화 하 는 동시에 프로그램의 길이 가 커지 기 때문에 더 많은 ROM 이 필요 하 다.이러한 최 적 화 를 사용 하면 Inline 함수 가 자주 호출 되 고 몇 줄 의 코드 만 포함 할 때 가장 효과 적 입 니 다.
7.      함수 호출 매개 변수 감소
전역 변 수 를 사용 하 는 것 이 함수 전달 매개 변수 보다 효율 적 입 니 다.이렇게 하면 함수 호출 매개 변수 가 스 택 에 들 어가 고 함수 가 완 료 된 후에 매개 변수 가 스 택 에서 나 오 는 데 필요 한 시간 을 제거 합 니 다.그러나 전역 변 수 를 사용 하기 로 결정 하면 프로그램의 모듈 화 와 재 입 에 영향 을 줄 수 있 으 므 로 신중하게 사용 해 야 합 니 다.
8.      static - 로 컬 함 수 를 정적 으로 표시 합 니 다.
함수 가 실행 파일 에 만 사용 된다 면 내부 연결 을 강제 하기 위해 정적 (static) 으로 설명 합 니 다.그렇지 않 으 면 기본적으로 함 수 를 외부 연결 로 정의 합 니 다.이렇게 하면 일부 컴 파일 러 의 최적화, 예 를 들 어 자동 내 연 에 영향 을 줄 수 있다.
9.      매개 변수, 반환 값, 부분 변수
가능 한 한 32bit 데이터 형식 사용 하기;대부분의 ARM 프로세서 의 동작 은 32bit 이 고 8bit 또는 16bit 는 작업 의 명령 수 (코드 1) 를 증가 시 키 며 경계 정렬 을 확보 할 수 있 기 때 문 입 니 다.
매개 변 수 는 4 개 를 초과 하지 마 십시오. 반환 값 은 가능 한 32bit 데이터 형식 입 니 다. ARM 은 ATPCS 요구 에 따라 앞의 네 개의 매개 변 수 는 레지스터 (r0 - r3) 로 전달 하고 반환 값 은 r0 으로 전달 하 며 나머지 매개 변 수 는 스 택 으로 전달 합 니 다.
부분 변 수 는 12 개 를 초과 하지 마 십시오. ARM 컴 파일 러 는 보통 전역 변 수 를 저장 공간 에 위치 시 키 고 부분 변 수 는 유 니 버 설 레지스터 에 배분 합 니 다. ARM 에서 사용 할 수 있 는 레지스터 는 12 개 입 니 다.
intwordinc(inta) 		word_inc 
{ 			ADD a1,a1,#1 
	return a + 1; 	MOV pc,lr 
} 		
shortshortinc(shorta)	short_inc 
{			ADD a1,a1,#1 
 	return a + 1;	MOV a1,a1,LSL #16 
}			MOV a1,a1,ASR #16
 			MOV pc,lr 

charcharinc(chara) 	char_inc 
{ 			ADD a1,a1,#1 
	return a + 1; 	AND a1,a1,#&ff 
} 			MOV pc,lr 
    ,   3 2              8  16    。

10. 나눗셈
ARM 명령 은 정수 나 누 기 를 제공 하지 않 았 고 나 누 기 는 C 언어 함수 라 이브 러 리 의 코드 (기호 형 rt sdiv 와 부호 형 이 없 는 rt udiv) 로 이 루어 졌 다.32 자리 수의 나눗셈 은 20 ~ 140 주기 가 필요 하 다.가능 한 한 곱 하기 로 나 누고 이 위 연산 에 협조 하 다.
11. 포인터
부분 변수 로 공공 하위 표현 식 의 값 을 저장 합 니 다. 이 표현 식 은 한 번 만 값 을 구 할 수 있 도록 합 니 다.메모리 접근 을 포함 하 는 표현 식 을 저장 하기 위해 새로운 부분 변 수 를 만 듭 니 다. 이 표현 식 에 대해 서 만 값 을 구 할 수 있 습 니 다.
예 를 들 어 아래 코드 는 앞의 코드 가 뒤의 것 보다 좋다.
int a=data[n];b+=a;c+=a;
b+=data[n];c+=data[n];

12. 조건 집행, 순환 종료 의 조건
ARM 명령 은 조건 부 로 실 행 될 수 있 기 때문에 cpsr 를 충분히 이용 하면 프로그램 이 더욱 효율 적 입 니 다.
순환 구조 에서 순환 의 종료 조건 은 순환 의 효율 에 심각 한 영향 을 미 칠 뿐만 아니 라 ARM 명령 의 조건 집행 특성 도 있 기 때문에 순환 의 종료 조건 을 쓸 때 count - down - to - zero 구 조 를 사용 해 야 한다.이렇게 컴 파 일 러 는 CMP (비교) 와 BLE (작 으 면 점프) 두 명령 을 BNE (0 이 아니면 점프) 명령 으로 대체 할 수 있 으 며 코드 사 이 즈 를 줄 일 뿐만 아니 라 ARM 실행 속도 도 빨 라 진다.
조건 판단 은 가능 한 한 0 과 비교 하고 이 유 는 같다.
13. 순환 구조
계수 감소 순환 을 사용 하 는 것 이 계수 증가 순환 보다 좋 습 니 다. 종료 조건 은 가능 한 한 i 를 쓰 십시오! =0 ;
순환 변수 시작 값 은 변수 이 고 0 이 아 닌 경우 do - while 로 순환 하 는 것 이 좋 습 니 다 (종료 조건 은 뒤에 있 습 니 다).
만약 에 순환 체 가 너무 간단 하 다 면 예 를 들 어 4 주기 보다 적 으 면 순환 체 (순환 체 코드 를 몇 번 반복 적 으로 쓰 는 것) 를 펼 칠 수 있다. 순환 체 코드 는 순환 자체 의 실행 주기 가 길 고 점프 명령 이 흐름 선 을 끊 는 것 을 줄 일 수 있다.
함수 내부 순환 에 사용 되 는 부분 변수의 데 이 터 를 최대한 제한 하고 최대 12 개 를 초과 하지 마 십시오. 그러면 컴 파일 러 는 그들 을 모두 ARM 레지스터 에 분배 할 수 있 습 니 다.(변수 개수 가 레지스터 개수 보다 많 을 때 레지스터 에 불 러 오지 않 은 변 수 는 연산 이 필요 할 때 일시 적 으로 사용 하지 않 는 레지스터 R 을 찾 아 변 수 를 불 러 오고 R 에 저 장 된 변 수 는 다시 연산 이 필요 할 때 사용 하지 않 는 레지스터 를 다시 찾 아 다시 불 러 와 야 합 니 다. 즉, 변수 개수 가 레지스터 개수 보다 많 을 때 한 변 수 를 여러 번 사용 할 수 있 습 니 다.레지스터 를 찾 고 레지스터 를 여러 번 불 러 오고 여러 번 바 뀌 는 과정);
14. 흐름 선 을 원활 하 게 유지한다.
파이프라인 차단 상황 은 순환 분해 등 을 통 해 개선 할 수 있 습 니 다. 하나의 순환 은 점프 명령 이 순환 명령 에서 차지 하 는 비중 을 줄 이 고 코드 효율 을 높 일 수 있 습 니 다. 다음은 메모리 복사 함수 로 ARM 설명 을 하 겠 습 니 다.
void memcopy(char *to, char *from, unsigned int nbytes) 
{ 
	while(nbytes--)ARM 
	*to++ = *from++; 
}

 
간단 한 견 해 를 위해 nbytes 가 16 인 ARM 배수 (나머지 처리 생략) 를 가정 합 니 다. 위의 함 수 는 바이트 하 나 를 처리 할 때마다 한 번 의 판단 과 점프 를 해 야 합 니 다. 그 중의 순환 체 를 다음 과 같이 분해 할 수 있 습 니 다.
void memcopy(char *to, char *from, unsigned int nbytes) 
{ 
	while(nbytes) { 
		*to++ = *from++; 
		*to++ = *from++; 
		*to++ = *from++; 
		*to++ = *from++; 
		nbytes - = 4; 
	} 
}

이렇게 되면 순환 체 의 명령 수 는 증가 하 였 으 나 순환 횟수 는 감소 하 였 다. 점프 명령 ARM 이 가 져 온 부정적인 영향 은 약화 되 었 다. ARM 7 프로세서 32 비트 길이 의 특성 을 이용 하여 상기 코드 는 다음 과 같이 조정 할 수 있다.
void memcopy(char *to, char *from, unsigned int nbytes) 
{ 
	int *p_to = (int *)to; 
	int *p_from = (int *)from; 
	while(nbytes) { 
		*p_to++ = *p_from++; 
		*p_to++ = *p_from++; 
		*p_to++ = *p_from++; 
		*p_to++ = *p_from++; 
		nbytes - = 16; 
	} 
}

 최 적 화 된 후 한 번 의 순환 으로 16 개의 바이트 를 처리 할 수 있 습 니 다. 점프 명령 에 따 른 영향 ARM 은 더욱 줄 어 들 었 습 니 다. 그러나 조 정 된 코드 는 코드 양 에 있어 서 증가 한 것 을 알 수 있 습 니 다.
15. 영화 속 RAM 활용
일부 업 체 가 생산 하 는 ARM 칩 에는 일 정량의 RAM 이 집적 되 어 있다. 예 를 들 어 Atmel 회사 의 AT91R 40807 에는 128 KB 의 RAM 이 있 고 샤프 회사 의 LH 75400 / LH 75401 에는 32KB 의 RAM 이 있다.
프로세서 가 필름 내 RAM 에 접근 하 는 속도 가 외부 RAM 에 접근 하 는 속도 보다 빠 르 기 때문에 가능 한 한 프로그램 을 필름 내 RAM 에 불 러 와 서 실행 해 야 합 니 다. 프로그램 이 너무 커서 필름 내 RAM 에 완전히 넣 을 수 없다 면 ARM 은 가장 빈번 한 데이터 나 프로그램 세그먼트 를 필름 내 RAM 으로 불 러 와 프로그램 운행 효율 을 높이 는 것 을 고려 할 수 있 습 니 다.
16. 참조
http://blog.csdn.net/quanming1119/article/details/450545
http://www.52rd.com/Blog/Detail_RD.Blog_qjacao_25022.html
http://blog.csdn.net/chenhaitao123/article/details/6222596 (구조 체 메모리 의 레이아웃)
http://www.builder.com.cn/2008/0416/818525.shtml

좋은 웹페이지 즐겨찾기