【发布时间】:2019-06-19 19:45:37
【问题描述】:
我使用数组编写了一个 C 代码,以了解我的英特尔 i7 8750 上的缓存行为,其中 L1d = 32k、L2 = 258k、L3:912k,行大小为 64 字节,设置大小 = 8。The trend I see for my code 我试图了解我从代码输出中获得的输出。 如果 LRU 是缓存的替换策略,我的代码中还可以做些什么来确保我获得最少的缓存未命中?
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
#define BILLION 1000000000L
struct student
{
char name[64];
};
int main(int argc, char* argv[])
{
int m, i, p;
char* n;
char mn[64];
u_int64_t diff;
struct timespec start, end;
m = strtol(argv[1], &n, 0);
struct student* arr_student = malloc(m * sizeof(struct student));
for(u_int64_t i = 0; i < m; i++ )
{
strcpy(arr_student[i].name, "abc");
}
/* 100 runs to ensure cache warmup and linear access time calculation*/
for (int j = 0; j<100; j++){
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
for(u_int64_t i = 0; i < m; i+=8){
strcpy(mn,arr_student[i].name);
if(i < (m-8)){
strcpy(mn,arr_student[i+1].name);
strcpy(mn,arr_student[i+2].name);
strcpy(mn,arr_student[i+3].name);
strcpy(mn,arr_student[i+4].name);
strcpy(mn,arr_student[i+5].name);
strcpy(mn,arr_student[i+6].name);
strcpy(mn,arr_student[i+7].name);
}
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
}
diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
printf("Time take for linear read operation only: %llu nanoseconds\n", (long long unsigned int) diff / 8 );
free(arr_student);
return 0;
}
我看到了一个趋势,随着数组大小的增加,循环执行步长为 8 的执行时间会花费越来越多的时间。我希望它保持不变,并且仅在 CPU 必须查看 L2 时才会增加,即当数组大小增长到超出 L1 可以容纳的范围时。我希望看到这样的结果:https://www.google.com/search?q=cache+performance+trend+l1+l2&rlz=1C1GCEA_enUS831US831&source=lnms&tbm=isch&sa=X&ved=0ahUKEwi9jqqApYrgAhXYFjQIHR39BtwQ_AUIDygC&biw=1280&bih=913#imgrc=5JVNAazx3drZvM:
当我将 diff 除以 m 时,为什么会得到反向趋势?我无法理解这种趋势。
请帮忙?
【问题讨论】:
-
我真的不明白你的问题。如果增加 m,则循环中的迭代次数将线性增长。至少,您应该将您的时间除以 m(并确保您始终准确地循环 m 次)。此外,测量 100 次迭代的时间以提高测量精度。但是不要指望惊人的效果,因为您以非常确定性和缓存友好的方式获取数据,并且英特尔有一个高效的预取器。
-
编辑代码以将时间除以 8,以确保我得到的时间是每个数组元素(64 字节)。我增长 m 以检查不适合 L1 的数组的每 64 个字节的访问时间,并且 CPU 必须转到 L2 才能找到这些元素。在这种情况下,我希望看到每 64 个字节的访问时间会有很大差异。
-
您正在循环 m 个元素(正好是 8
-
感谢您的意见。我可以做些什么来优化这里的代码吗?可以在这里看到这样的趋势:google.com/…:
-
为什么我将 diff 除以 m 时会反转趋势?我无法理解这种趋势。