嘿所以我有一个用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循环以进一步改善空间局部性没有任何想法。
任何人都可以指导我如何编写更好的缓存友好循环。
P.S。我正在做这些问题,作为我自己学习计算机体系结构书的一部分,我没有教练寻求帮助。
答案 0 :(得分:1)
发布的代码; CPU将按升序读取缓存行并按升序写入缓存行。没有更好的(更多缓存友好)访问模式(部分原因是CPU的“硬件预取器”)。
您可以做的唯一其他事情是减少数据的大小(但我看不出如何)。
还有一些方法可以改进代码(clflush
,SIMD),这对缓存未命中率没有任何影响。