【发布时间】:2014-12-18 09:19:15
【问题描述】:
我正在尝试优化在并行区域 (OpenMP) 中调用的部分代码。我使用 Intel VTune Amplifier 2015 进行了内存访问分析,对结果有点困惑。我使用 Intel Composer 2015 重复了优化级别 O1、O2 和 O3 的分析,但结果是相同的。 Amplifier 声称,大多数 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;
但是整个执行过程需要更多的时间(这很清楚)。但我可以相信哪些结果?或者我可以使用哪些替代软件进行测试。
提前致谢!
【问题讨论】:
-
如果您想验证结果,cachegrind 是另一个工具。
-
每次执行函数会导致多少缓存未命中?该工具是否会告诉您这些是 i-cache 还是 d-cache 未命中?
-
这个函数是在一个紧密的循环中调用的吗?
-
硬件事件可能归因于至少 +-1 指令偏移/错误。采样硬件事件 - 引入更多的不准确性。而且即使你提高了很多准确率,你仍然很难得到准确的答案,因为它是乱序架构,这意味着你“坐等”执行端口的时刻与“发布”的时刻不同“ 操作说明。并且 -O2/-O3 编译后的二进制文件的调试信息不准确也存在问题,这也可能导致在映射指令、源代码行和硬件事件时产生很大的混淆。
-
因此,如果您真的想找出根本原因,请尝试在 VTune 中探索汇编,以确保源代码行和指令(调试信息)之间的相关性符合您的预期。并注意绝对缓存未命中数(如建议的那样),以了解抽样的统计影响。
标签: c++ caching intel-vtune