c - 提高缓存命中率

标签 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 循环以进一步提高空间局部性。

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

附注我正在做这些问题,作为我自学计算机体系结构书籍的一部分,并且我没有老师可以寻求帮助。

最佳答案

对于发布的代码; CPU 会按升序读取缓存行并按升序写入缓存行。没有比这更好(对缓存更友好)的访问模式了(部分归功于 CPU 的“硬件预取器”)。

您唯一可以做的其他事情就是减小数据的大小(但我不知道如何实现)。

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

关于c - 提高缓存命中率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43485541/

相关文章:

c - epoll 事件不会引发 SIGIO

amazon-web-services - 您如何在无服务器架构中平衡 nosql 存储和缓存?

cpu-architecture - 如何判断真值表是否有错误?

c++ - 是否可以更快地执行更复杂的循环?

c - 如何检查指针指向 C 中的有效字符串

c |比较字符串格式

c# - 如何修改CPU Cache L1、Cache L2、Cache L3?

caching - 如何查看末级缓存中有多少个切片?

c - writev(或pwritev)会与c中的O_DIRECT冲突吗?

php - 使用 Tinybrick 的 Lightspeed 进行高级打洞