是什么导致我的代码中的缓存未命中?

时间:2014-12-18 09:19:16

标签: c++ caching vtune

我正在尝试优化在并行区域(OpenMP)中调用的部分代码。我使用英特尔VTune Amplifier 2015进行了内存访问分析,对结果感到有点困惑。我用英特尔Composer 2015重复了优化级别为O1,O2和O3的分析,但结果是一样的。放大器声称,大多数LLC未命中出现在以下三行中:

__attribute__ ((aligned(64)))    double       x[4] = {1.e0,-1.e0, 0.e0, 0.e0};
__attribute__ ((aligned(64)))    double       y[4] = {0.e0,-1.e0, 1.e0, 0.e0};
__attribute__ ((aligned(64)))    double       z[4] = {0.e0, 0.e0,-1.e0, 1.e0};

数据已对齐,因为稍后会在矢量化代码中访问它。我不能在这里发布整个代码,因为它有版权。这大约是此函数中总缓存未命中的75%,尽管代码中稍后会有大量计算和其他数组。 对于O0优化,我得到了更真实的结果,因为那里有像

这样的行
res[a] += tempres[start + b] * fact;

但整个执行需要更多的时间(很清楚)。但是我可以信任哪些结果?或者我可以使用哪种替代软件进行测试。

提前致谢!

1 个答案:

答案 0 :(得分:0)

仅查看百分比可能会产生误导(100%中的75%低于1000%的10%) - 当您进行比较时,您需要查看绝对未命中数。

缓存行为也很难直观,特别是与编译器优化和CPU管道相结合 看起来优化的构建主要是在初始化时错过了缓存(并不太令人惊讶),但设法将整个计算保持在缓存中,所以我不会在这里看到问题。

如果您想确定,您需要研究生成的程序集和硬件的参考手册。

搜索确认您的期望的工具很大程度上是浪费时间,因为您无法确定 工具不属于那个工具错误。