提高缓存命中率

时间:2017-04-19 02:56:41

标签: c caching cpu-architecture

嘿所以我有一个用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。我正在做这些问题,作为我自己学习计算机体系结构书的一部分,我没有教练寻求帮助。

1 个答案:

答案 0 :(得分:1)

发布的代码; CPU将按升序读取缓存行并按升序写入缓存行。没有更好的(更多缓存友好)访问模式(部分原因是CPU的“硬件预取器”)。

您可以做的唯一其他事情是减少数据的大小(但我看不出如何)。

还有一些方法可以改进代码(clflush,SIMD),这对缓存未命中率没有任何影响。