2017-04-19 39 views
0

嘿所以我有写在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的定义不是很缓存友好的,因为它有一吨的填充。

于是,我改变根据allignment requiirements这个定义 -

typedef struct { 
    int n1; 
    int n2; 
    double f1; 
    double f2; 
    char c1; 
    char c2; 
} data_new; 

但是这给了我大约只有10缓存性能%的增幅。我对如何修改for循环以进一步改善空间局部性没有任何想法。

任何人都可以指导我如何能够编写更好的缓存友好的循环。

P.S.作为我对计算机体系结构书的自学研究的一部分,我正在做这些问题,而且我没有教师寻求帮助。

+0

我们不是代码评论网站。 **阅读代码评论的常见问题解答**,如果你的代码是正确的,它可能是他们的候选人。但是你应该提供明确的更多信息,市场上有很多非常不同的CPU。 – Olaf

+0

@Olaf会/ proc/cpuinfo有帮助吗?此外,我不期待CPU具体的答案。只是关于如何改进这种循环的缓存性能的一般准则。 –

+0

不在这里,不够。对不起,还是太宽泛了。敬请谅解。 – Olaf

回答

1

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

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

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