c - Linux C++ : test of the cacheline size performance effect not as expected

标签 c linux performance caching size

据说对于普通 x86 cpu(i7 mac),cpu 缓存行大小为 64 字节,因此如果使用数组大小​​<64,它将仅存在于一个缓存行中并且速度很快,当缓存行大小为越大,程序会变慢。

下面是我的程序:

#include<sys/time.h>
#include<stdlib.h>
#include<stdio.h>
size_t cacheline=16;
int main(int argc,char*argv[]){
    size_t loopCount=2000000000;
    if(argc==2){loopCount=atol(argv[1]);}
    printf("loop=%ld\n",loopCount);
    int array[cacheline];
    for(size_t a=0;a<cacheline;++a){
        array[a]=a;
    }
    size_t c=0;
    long sum=1;
    for(size_t i=0;i<loopCount;++i){
        if(c==cacheline)c=0;
        sum+=array[c++];//
    }
    printf("sum=%ld\n",sum);
    return 0;
}

clang++ test07_cacheline.cpp -O2 -o test07_cacheline && time ./test07_cacheline 2000000000
loop=2000000000
sum=63354543092609

real    0m2.810s
user    0m2.794s
sys 0m0.009s

但在我的测试程序中我发现,无论我将“数组”的大小设置为16、64、256或65536,时间执行时间基本相同。理论或我的程序设计有什么问题?我也尝试了一些来自互联网的其他程序,结果相同,如下所示:

#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
long timediff(clock_t t1,clock_t t2){
    return (t2-t1)*1000/CLOCKS_PER_SEC;
}
int main(int argc,char*argv[]){
    int array_size=65536;
    if(argc>=2)array_size=atoi(argv[1]);
    int repeat_times=2000000000;
    long array[array_size];
    for(int i=0;i<array_size;++i){
        array[i]=i;
    }
    int j=0;
    int k=0;
    int c=0;
    clock_t start=clock();
    while(j++<repeat_times){
        if(k==array_size){k=0;}
        c+=array[k++];
    }
    clock_t end=clock();
    printf("c=%d,%lu\n",c,timediff(start,end));
    return 0;
}

g++ test08_cacheline.cpp -O2 -o test08_cacheline && ./test08_cacheline
c=1865233920,2800

无论array_size如何位。那么关于高速缓存行如何影响我的程序性能的任何解释?

最佳答案

您缺少的是这两个执行都在利用数据局部性

您正在读取连续数组。您的缓存将读取数组的连续 block 。唯一的区别在于您加载 block 的次数。

这个数字并没有那么大,此外,编译器能够预测何时加载新 block ,尤其是当您标记了一些优化规则(例如矢量化)时。

更多信息请阅读here

如果您想了解性能如何变化,请尝试以这种方式修改您的代码:

   while(j++<repeat_times){
        if(k==array_size){k=0;}
        int position = ((c+k)*j)%array_size;
        c+=array[position];
        k++;
    }

这样您将失去数据本地性。


更新

性能更多地取决于内存访问模式而不是缓存大小。更准确地说,如果程序主要是顺序的,缓存大小就不是什么大问题。如果有相当多的随机访问,缓存大小真的很重要。

如果您想尝试查看缓存大小如何导致不同的性能,您可以尝试:

  1. 删除随机访问的数据局部性
  2. 然后改变数组的大小。

通过这种方式,如果每次随机访问数组的大小都适合您的缓存,则该 block 将已经进入缓存。

注意您不是唯一在您的 PC 上使用缓存的人!

关于c - Linux C++ : test of the cacheline size performance effect not as expected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43559277/

相关文章:

c - 关于指针

java - C JNI 帮助处理复杂代码

linux - 在 bash 脚本中,如何将文本文件中包含的值提供给程序执行的开关?

linux - 使用scapy高频发送UDP ping,为什么只收到前几个ICMP端口不可达报文?

javascript - 模板与 templateUrl 以及样式与 styleUrls - 性能

sql - MSSQL 查询帮助?应该很容易,但我必须要更多的咖啡?

c - 瑞士星历库不会在 Ubuntu 上运行

c - 两个无符号长整型的 printf 奇怪问题

linux - 如何在 PAM 之后而不是在重新映射用户之前告诉 SSH 到 setuid

performance - 与 Internet 相比,企业网络中的 Azure Web 应用程序性能较差