캐시 크기 (L1, L2, L3)를 얻기위한 프로그램을 작성하고 싶습니다. 나는 그것의 일반적인 생각을 안다. CPU 캐시 크기 및 레벨을 얻기위한 프로그램 작성
- 큰 배열을 다른 크기의 그것의
- 액세스 부분마다 할당합니다.
그래서 나는 작은 프로그램을 작성했습니다.
#include <cstdio>
#include <time.h>
#include <sys/mman.h>
const int KB = 1024;
const int MB = 1024 * KB;
const int data_size = 32 * MB;
const int repeats = 64 * MB;
const int steps = 8 * MB;
const int times = 8;
long long clock_time() {
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return (long long)(tp.tv_nsec + (long long)tp.tv_sec * 1000000000ll);
}
int main() {
// allocate memory and lock
void* map = mmap(NULL, (size_t)data_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (map == MAP_FAILED) {
return 0;
}
int* data = (int*)map;
// write all to avoid paging on demand
for (int i = 0;i< data_size/sizeof(int);i++) {
data[i]++;
}
int steps[] = { 1*KB, 4*KB, 8*KB, 16*KB, 24 * KB, 32*KB, 64*KB, 128*KB,
128*KB*2, 128*KB*3, 512*KB, 1 * MB, 2 * MB, 3 * MB, 4 * MB,
5 * MB, 6 * MB, 7 * MB, 8 * MB, 9 * MB};
for (int i = 0; i <= sizeof(steps)/sizeof(int) - 1; i++) {
double totalTime = 0;
for (int k = 0; k < times; k++) {
int size_mask = steps[i]/sizeof(int) - 1;
long long start = clock_time();
for (int j = 0; j < repeats; j++) {
++data[ (j * 16) & size_mask ];
}
long long end = clock_time();
totalTime += (end - start)/1000000000.0;
}
printf("%d time: %lf\n", steps[i]/KB, totalTime);
}
munmap(map, (size_t)data_size);
return 0;
}
그러나, 결과가 너무 이상해 : 여기 내 코드의
1 time: 1.989998
4 time: 1.992945
8 time: 1.997071
16 time: 1.993442
24 time: 1.994212
32 time: 2.002103
64 time: 1.959601
128 time: 1.957994
256 time: 1.975517
384 time: 1.975143
512 time: 2.209696
1024 time: 2.437783
2048 time: 7.006168
3072 time: 5.306975
4096 time: 5.943510
5120 time: 2.396078
6144 time: 4.404022
7168 time: 4.900366
8192 time: 8.998624
9216 time: 6.574195
내 CPU는 인텔 (R) 코어 (TM) i3-2350M입니다. L1 캐시 : 32K (데이터 용), L2 캐시 256K, L3 캐시 3072K. 규칙을 따르지 않는 것 같습니다. 캐시 크기 나 캐시 수준에 대한 정보를 얻을 수 없습니다. 아무도 도움을 줄 수 있습니까? 미리 감사드립니다.
업데이트 : 따르 @Leeor 조언, 나는 j*64
대신 j*16
사용합니다. 새로운 결과 :
1 time: 1.996282
4 time: 2.002579
8 time: 2.002240
16 time: 1.993198
24 time: 1.995733
32 time: 2.000463
64 time: 1.968637
128 time: 1.956138
256 time: 1.978266
384 time: 1.991912
512 time: 2.192371
1024 time: 2.262387
2048 time: 3.019435
3072 time: 2.359423
4096 time: 5.874426
5120 time: 2.324901
6144 time: 4.135550
7168 time: 3.851972
8192 time: 7.417762
9216 time: 2.272929
10240 time: 3.441985
11264 time: 3.094753
두 개의 피크, 4096K 및 8192K. 아직도 이상해.
고맙습니다!. 대신 j * 64를 사용하지만 결과는 혼란 스럽습니다. 내 업데이트를 참조하십시오. –
@ KanLiu - 내 대답 – Leeor
업데이트, 잘 작동합니다! 고마워. –