【问题标题】:How to optimize cache performance?如何优化缓存性能?
【发布时间】:2019-06-19 19:45:37
【问题描述】:

我使用数组编写了一个 C 代码,以了解我的英特尔 i7 8750 上的缓存行为,其中 L1d = 32k、L2 = 258k、L3:912k,行大小为 64 字节,设置大小 = 8。The trend I see for my code 我试图了解我从代码输出中获得的输出。 如果 LRU 是缓存的替换策略,我的代码中还可以做些什么来确保我获得最少的缓存未命中?

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>

#define BILLION 1000000000L

struct student
{
    char name[64];
};

int main(int argc, char* argv[])
{

     int m, i, p;
     char* n;
     char mn[64];
     u_int64_t diff; 
     struct timespec start, end; 
     m = strtol(argv[1], &n, 0);

    struct student* arr_student = malloc(m * sizeof(struct student));

    for(u_int64_t i = 0; i < m; i++ )
    {      
         strcpy(arr_student[i].name, "abc");
    }

     /* 100 runs to ensure cache warmup and linear access time calculation*/ 

    for (int j = 0; j<100; j++){        

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
        for(u_int64_t i = 0; i < m; i+=8){
            strcpy(mn,arr_student[i].name);
     if(i < (m-8)){
    strcpy(mn,arr_student[i+1].name);
    strcpy(mn,arr_student[i+2].name);
    strcpy(mn,arr_student[i+3].name);
    strcpy(mn,arr_student[i+4].name);
    strcpy(mn,arr_student[i+5].name);
    strcpy(mn,arr_student[i+6].name);
    strcpy(mn,arr_student[i+7].name);
    }
    }
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
} 

diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;

printf("Time take for linear read operation only: %llu nanoseconds\n", (long long unsigned int) diff / 8 );

free(arr_student);

return 0;
}

我看到了一个趋势,随着数组大小的增加,循环执行步长为 8 的执行时间会花费越来越多的时间。我希望它保持不变,并且仅在 CPU 必须查看 L2 时才会增加,即当数组大小增长到超出 L1 可以容纳的范围时。我希望看到这样的结果:https://www.google.com/search?q=cache+performance+trend+l1+l2&rlz=1C1GCEA_enUS831US831&source=lnms&tbm=isch&sa=X&ved=0ahUKEwi9jqqApYrgAhXYFjQIHR39BtwQ_AUIDygC&biw=1280&bih=913#imgrc=5JVNAazx3drZvM:

当我将 diff 除以 m 时,为什么会得到反向趋势?我无法理解这种趋势。

请帮忙?

【问题讨论】:

  • 我真的不明白你的问题。如果增加 m,则循环中的迭代次数将线性增长。至少,您应该将您的时间除以 m(并确保您始终准确地循环 m 次)。此外,测量 100 次迭代的时间以提高测量精度。但是不要指望惊人的效果,因为您以非常确定性和缓存友好的方式获取数据,并且英特尔有一个高效的预取器。
  • 编辑代码以将时间除以 8,以确保我得到的时间是每个数组元素(64 字节)。我增长 m 以检查不适合 L1 的数组的每 64 个字节的访问时间,并且 CPU 必须转到 L2 才能找到这些元素。在这种情况下,我希望看到每 64 个字节的访问时间会有很大差异。
  • 您正在循环 m 个元素(正好是 8
  • 感谢您的意见。我可以做些什么来优化这里的代码吗?可以在这里看到这样的趋势:google.com/…:
  • 为什么我将 diff 除以 m 时会反转趋势?我无法理解这种趋势。

标签: c caching


【解决方案1】:

这里有一些关于内存对齐和代码优化的有用技巧:

一般来说,代码优化是时间和经验的问题。

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2013-06-16
    • 2016-02-02
    • 2014-08-06
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多