cache基础
对cache的掌握,对于linux工程师(其他的非linux工程师也一样)写出高效能代码,以及优化linux系统的性能是至关重要的。简单来说,cache快,内存慢,硬盘更慢。在一个典型的现代cpu中比较接近改进的哈佛结构,cache的排布大概是这样的:
l1速度> l2速度> l3速度> ram
l1容量< l2容量< l3容量data的时候,流水线可以直接命中cache,从而不打断。
预取的原理有点类似今天星期五,咱们在上海office,下周一需要北京分公司的人来上海office开会。于是,我们通知北京office的人周末坐飞机过来,这样周一开会的时候就不必等他们了。不预取的情况下,会议开始后,再等北京的人飞过来,会导致stall状态。
任何东西最终还是要落实到代码,talk is cheap,show me the code。下面这个是经典的二分查找法代码,这个代码是网上抄的。
特别留意ifdef do_prefetch包着的代码,它提前预取了下次的中间值。我们来对比下,不预取和预取情况下,这个同样的代码执行时间的差异。先把cpufreq的影响尽可能关闭掉,设置为performance:
barry@barry-hp-probook-450-g7:~$ sudo cpupower frequency-set --governor performancesetting cpu: 0setting cpu: 1setting cpu: 2setting cpu: 3setting cpu: 4setting cpu: 5setting cpu: 6setting cpu: 7 然后我们来对比差异:
开启prefetch执行时间大约10s, 不prefetch的情况下,11.6s执行完成,性能提升大约14%,所以周末坐飞机太重要了!
现在我们来通过基于perf的pmu-tools(下载地址:https://github.com/andikleen/pmu-tools),对上面的程序进行topdown分析,分析的时候,为了尽可能减小其他因子的影响,我们把程序通过taskset运行到cpu0。
先看不prefetch的情况,很明显,程序是backend_bound的,其中dram_bound占比大,达到75.8%。
开启prefetch的情况呢?程序依然是backend_bound的,其中,backend bound的主体依然是dram_bound,但是比例缩小到了60.7%。
dram_bound主要对应cycle_activity.stalls_l3_miss事件,我们通过perf stat来分别进行搜集:
我们看到,执行prefetch情况下,指令的条数明显多了,但是它的insn per cycle变大了,所以总的时间cycles反而减小。其中最主要的原因是cycle_activity.stalls_l3_miss变小了很多次。
这个时候,我们可以进一步通过录制mem_load_retired.l3_miss来分析究竟代码哪里出了问题,先看noprefetch情况:
焦点在main函数:
继续annotate一下:
明显问题出在array[mid] 80.00%):
继续annotate一下:
热点被分散了,预取缓解了memory_bound的情况。
避免false sharing
前面我们提到过,数据如果在一个cacheline,被多核访问的时候,多核间运行的cache一致性协议,会导致cacheline在多核间的同步。这个同步会有很大的延迟,是工程里著名的false sharing问题。
比如下面一个结构体
struct s{ int a; int b;} 如果1个线程读写a,另外一个线程读写b,那么两个线程就有机会在不同的核,于是产生cacheline同步行为的来回颠簸。但是,如果我们把a和b之间padding一些区域,就可以把这两个缠绕在一起的人拉开:
struct s{ int a; char padding[cacheline_size - sizeof(int)]; int b;} 因此,在实际的工程中,我们经常看到有人对数据的位置进行移位,或者在2个可能引起false sharing的数据间填充数据进行padding。这样的代码在内核不甚枚举,我们随便找一个:
它特别提到在tw_count后面60个字节(l1_cache_bytes - sizeof(atomic_t))的padding,从而避免false sharing:
下面这个则是通过移动结构体内部成员的位置,相关数据的cacheline分开的:
这个改动有明显的性能提升,最高可达9.9%。代码里面也有明显地注释,usage和parent原先靠地太近,一个频繁写,一个频繁读。移开了2边互相不打架了:
把理论和代码能对上的感觉真tnnd爽。无论是996,还是007,都必须留些时间来思考,来让理论和实践结合,否则,就变成漫无目的的内卷,这样一定会卷输的。内卷并不可悲,可悲的是卷不赢别人。
热式流量计的工作原理及设计
与高通、谷歌合作!从手机VR到XR,三星展开多重布局
消防应急疏散指示系统在某学校项目上的应用
目前市面上有哪几家厂商推出120W快充技术?
低功耗便携式射频巡更读写器设计
宋宝华:深入理解cache对写好代码至关重要
看传感器如何打造“最美公厕”
HDMI的发展历史介绍
什么是三极管的饱和工作状态?如何才能让使三极管进入饱和工作状态呢?
喜讯!热烈祝贺武汉芯源半导体顺利通过CQC质量管理体系认证
三星三季度开始生产QLED 8K电视:刷新率120Hz,尺寸不会低于65英寸
计算机网络各层作用及协议
南方测绘遥感数据自动处理+三维激光创新应用经验分享
螺杆支撑座在使用中需要注意的事项
APMS-10G智能化混浊度传感器的性能、使用注意事项及应用范围
一文解析Zen 4 的核心架构
溢价的iphone12什么时候上市 首批iPhone12订单发货了
九芯电子|公司已在东莞、长沙新建生产基地,满足业务规模不断扩张的战略需求!
什么是液晶显示器的亮度/自动背光调节
小容量EMMC-旺宏EMMC客户的不二之选