C/C++ 基于CPU Cache line 优化真的有效果吗?

您所在的位置:网站首页 cpu里的cache C/C++ 基于CPU Cache line 优化真的有效果吗?

C/C++ 基于CPU Cache line 优化真的有效果吗?

#C/C++ 基于CPU Cache line 优化真的有效果吗?| 来源: 网络整理| 查看: 265

直接分析代码,两个测试函数都是双重循环,总循环次数一致。

内部循环64次,8bit的fp紧密排布也会占满cache line,key也是,所以读进来的cache line都没有被浪费。

外循环里,由于key数组与fp数组交织排布,即两个测试访问的内存范围其实是一样的大的。

总的来看区别只是64bit的key涉及到的数据空间大了8倍而已。

那么会有cache miss嘛?会,但很少。

CPU有prefetch,并不是每次读数据才去缓存、内存里加载。循环的数据访问规律明显,CPU很快就能意识到访问数据的存放位置并提前加载。

当然由于key需要访问的内存量更大,如果prefetch或者内存读取速度跟不上计算速度,那key是更容易慢——不过这不是cache miss而是撞内存墙。而且现代CPU还没这么不堪,不至于连个循环加法都撑不住。

(补充一下,这里指的是未向量化的单核循环加法,现在的CPU做这种运算还不至于撞内存墙)

那么为什么64bit的运算反而更快了?

按照前面说的,内存访问上两者两者应该都没遇上瓶颈,那就该是运算上有区别咯!

在这里先不考虑SIMD的优化(毕竟SSE/AVX里64bit运算吞吐量就是8bit的8倍,不应该出现64bit运算更快的情况)。

其实其他答主已经提到了反汇编的结果:

64bit运算的反汇编更简洁、指令更少。

这时候可以查阅x86的指令集了,比如这里

一个标量整型加法指令,add,具有两个操作数a和b,操作是a=a+b。其中a可以是寄存器或内存地址,b可以是立即数/寄存器/内存地址。

但仔细看就能发现,a和b的位数都是一样的!(其实64位下往64位的RAX加个32位立即数是可以的,这里方便起见就只考虑32位了)

也就是说往一个uint32里加一个uint8,是不能由一条指令完成的!如果这个uint8是立即数,那编译时可以扩充到imm32,但如果这个uint8不是立即数,就需要其他办法做一个转化了,链接回答里出现的movzx就是干这个的,从内存读个uint8到32bit的寄存器。

代码性能本来就不止和cache有关,跟数据结构也是有很大关系的,而且uint8也不见得就比uint32来的快……



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3