嘿,所以我有一个用 c
编写的函数我必须提高其缓存性能。统计数据由 cachegrind
提供。但我完全陷入困境,无法获得超过 10% 的性能提升。我真的需要这方面的帮助。
这是函数:
#define LARGER 50000
typedef struct {
char c1;
double f1;
int n1;
char c2;
int n2;
double f2;
} data;
char* func()
{
data* B = (data*) calloc(LARGER, sizeof(data));
if (!B) return 0;
double sum_f = 0.0;
double sum_n = 0;
char* sum_c = (char*) malloc(( 2 * LARGER + 1) * sizeof(char));
sum_c[2 * LARGER] = '\0';
int i;
for(i = 0; i < LARGER; i++)
{
sum_f += B[i].f1 + B[i].f2;
sum_n += B[i].n1 + B[i].n2;
sum_c[2 * i] = B[i].c1;
sum_c[2 * i + 1] = B[i].c2;
}
free(B);
return sum_c;
}
我注意到的第一件事是 struct data
的定义缓存不太友好,因为它有大量的填充。
因此,我根据对此的对齐要求更改了定义 -
typedef struct {
int n1;
int n2;
double f1;
double f2;
char c1;
char c2;
} data_new;
但这只能使缓存性能提高 10% 左右。我不知道如何修改 for 循环以进一步提高空间局部性。
任何人都可以指导我如何编写更好的缓存友好循环。
附注我正在做这些问题,作为我自学计算机体系结构书籍的一部分,并且我没有老师可以寻求帮助。
最佳答案
对于发布的代码; CPU 会按升序读取缓存行并按升序写入缓存行。没有比这更好(对缓存更友好)的访问模式了(部分归功于 CPU 的“硬件预取器”)。
您唯一可以做的其他事情就是减小数据的大小(但我不知道如何实现)。
还有一些改进代码的方法(clflush
、SIMD),这些方法不会对缓存未命中率产生任何影响。
关于c - 提高缓存命中率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43485541/