编译器优化使用PAPI对FLOP和L2 / L3缓存丢失率的影响

时间:2014-10-29 19:04:42

标签: c intel compiler-optimization cpu-cache flops

所以我们的任务是编译一些代码(我们应该把它当作黑盒子),使用不同的intel编译器优化标志(-O1和-O3)以及矢量化标志(-xhost和-no-vec)并观察以下变化:

  • 执行时间
  • 浮点运算(FPOs)
  • L2和L3缓存丢失率

执行这些优化之后,考虑到编译器为了提高效率而对代码所做的所有更改,我们注意到了执行时间的下降,这是预期的。但是,我们也注意到FPO的数量有所下降,虽然我们知道它是一件好事,但我们不确定它为什么会发生。此外,我们注意到(并且无法解释)L2缓存未命中率的增加(随着优化级别的增加而增加),但缓存访问没有显着增加,并且L3级别几乎没有变化。

根本没有使用矢量化或优化产生了L2缓存未命中率的最佳结果,我们想知道你们是否可以给我们一些见解,以及我们可以用来支持的文档,文献和资源加深我们对这个主题的了解。

谢谢。

编辑:使用的编译器选项是:

  • O0 -no-vec(最高执行时间,最低L2缓存未命中)
  • O1(执行时间越少,L2缓存未命中率越高)
  • O3(执行时间更短,甚至更高的L2缓存未命中)
  • xhost(-O3执行时间,最高L2缓存未命中的相同顺序)

更新

虽然整体L2缓存访问量略有下降,但实际未命中率却大幅增加。

使用-0O -no-vec

使用中的挂钟时间:13,957,075

  • 二级缓存未命中:207,460,564
  • L2缓存访问:1,476,540,355
  • L2缓存未命中率:0.140504
  • L3缓存未命中:24,841,999
  • L3缓存访问:207,460,564
  • L3缓存未命中率:0.119743

使用-xhost

使用中的挂钟时间:4,465,243

  • L2缓存未命中:547,305,377
  • L2缓存访问:1,051,949,467
  • L2缓存未命中率:0.520277
  • L3缓存未命中:86,919,153
  • L3缓存访问:547,305,377
  • L3缓存未命中率:0.158813

2 个答案:

答案 0 :(得分:2)

减少浮点数的数量:
通过优化,编译器可以提升循环,熔丝常数,预计算表达式等常用计算。

增加缓存未命中率:
如果编译器使用矢量化,并且每次都加载一个完整的矢量宽度数据,那么它将总共使用更少的内存负载。但是每当它以预测器没有预料到的方式访问高速缓存行时,它仍然会导致高速缓存未命中。一起,你的负载较少,但触摸的高速缓存行数相同,所以未命中率可能更高。

答案 1 :(得分:2)

对于较少的浮点操作,EOF的答案有一个很好的解释:-ffast-math样式组合操作,所以我只回答其他部分。

这个问题没有关于使用什么CPU微体系结构的信息,但至少它被标记为

在Intel CPU上,有一些逻辑可以预取到L1,还有更复杂的逻辑可以预取到L2(来自L3或主存储器)。每个核心都有自己的L2,但缓存层次结构的较低级别是共享的,因此它是放置主预取逻辑的明显位置。

如果您的读取速度低于内存带宽限制,则您的负载将达到L2,因为硬件预取器已将这些线路读入L2。 如果预取无法跟上,您将获得L2缓存未命中

更少的更宽的负载而不是更多的标量负载也意味着缺少%将导致更差的矢量。 (EOF的答案已经提到了这一点)。然而,这种效果并不能解释L2未命中绝对数量的增加,只有(部分)未命中%变化。但是,在查看数据时要记住这一点仍然很重要。

来自英特尔的优化指南(标签wiki中的链接),第2.3.5.4节:数据预取

  

数据预取到L2和最后一级缓存

     

Streamer :此预取程序监视来自L1缓存的读取请求,用于升序和降序地址序列....当转发或   检测到后向请求流,预取了预期的高速缓存行。预取缓存   行必须在同一个4K页面中。

     
      
  • 流传输器可以在每次L2查找时发出两个预取请求。流光可以达到20   加载请求之前的行。
  •   
  • 动态调整每个核心的未完成请求数。如果没有多少   出色的请求,流光预告进一步提前。如果有很多优秀的   要求它仅向有限责任公司提供预取,并且要求不远。
  •   
  • 当缓存行远远超前时,它只预取到最后一级缓存而不是L2。这个   方法避免在L2缓存中替换有用的缓存行。
  •   
  • 检测并维护多达32个数据访问流。对于每个4K字节页面,您可以进行维护   可以维持一个前向和一个后向流。
  •   

这是来自Sandybridge部分,但Haswell和Skylake部分没有详细介绍预取的变化。他们说"改进了预取",但可能它是相同的基本设计,只是更好的启发式和/或更好地调整现有的启发式,以及类似的东西。

感谢@HansPassant:他对这个问题的评论使我想到了预备不跟上。