성능이 저하되고 최악의 경우 프로그램이 충돌하는 포인터가 잘못 정렬되지 않았습니다 (잘못된 c 프로그램을 컴파일하기에 충분히 좋은 컴파일러라고 가정).잘못 정렬 된 포인터 성능
글쎄, 다음 코드는 정렬 된 버전과 정렬되지 않은 버전간에 성능 차이가없는 것 같습니다. 왜 그런가요?
/* brutality.c */
#ifdef BRUTALITY
xs = (unsigned long *) ((unsigned char *) xs + 1);
#endif
...
/* main.c */
#include <stdio.h>
#include <stdlib.h>
#define size_t_max ((size_t)-1)
#define max_count(var) (size_t_max/(sizeof var))
int main(int argc, char *argv[]) {
unsigned long sum, *xs, *itr, *xs_end;
size_t element_count = max_count(*xs) >> 4;
xs = malloc(element_count * (sizeof *xs));
if(!xs) exit(1);
xs_end = xs + element_count - 1; sum = 0;
for(itr = xs; itr < xs_end; itr++)
*itr = 0;
#include "brutality.c"
itr = xs;
while(itr < xs_end)
sum += *itr++;
printf("%lu\n", sum);
/* we could free the malloc-ed memory here */
/* but we are almost done */
exit(0);
}
가 집계하고
gcc -pedantic -Wall -O0 -std=c99 main.c
for i in {0..9}; do time ./a.out; done
나는 당신의 트릭을 이해하지 못한다는 것을 인정합니다. size_t는 유형입니다. 그래서 size_t-1은 무엇입니까? 작은 정련은 sum + = itr ++의 마지막 반복은 BRUTALITY가 정의되었을 때 할당 한 것 이상으로 메모리를 읽는다는 것입니다. 나는 printf와 쉘 호출과 루핑을 죽일 것이다. 프로그램 내부의 모든 타이밍을 수행하고 프로그램 내부에 10x 루프를 추가하십시오. –
음, xs_end는 마지막 요소를 지키지 않고 마지막 요소를 가리 킵니다.이 경우 마지막 할당 된 버퍼를 지나서 쓰게됩니다. 그리고 size_t는 부호없는 유형이므로 표준에서는 ... "Google"SIZE_MAX 휴대용을 보장합니다. 그리고 아니오, printf는 심지어 -O2를 사용할 때 컴파일러가 모든 코드를 배수구 아래로 던지지 않도록 보장합니다. –
오, 죄송합니다. size_t에 -1 형 변환합니다. 그리고 맞습니다. 정상적인 xs_end 컨벤션을 가정했습니다. 나는 여전히 당신이 printf() 및 다른 무거운 OS 물건을 루프 밖으로 유지하려고해야한다고 생각합니다. 오 강한 생각이 있습니다. 대신 새로운 대답을하겠습니다. –