我正在尝试优化 sin/cos 逼近函数。它的核心是一个简单的霍纳方案,由一堆乘法和加法组成。编译器是 VS2017 的 MSVC,处理器是 Intel Xeon E5-1650,超线程开启(但如果关闭,观察结果基本相同)。
使用 Intel 的 VTune Amplifier 2019,我在随机双精度数(-2 pi 和 2 pi 之间)上运行函数超过 1 分钟获得了分析结果(当然是发布版本),在所示部分中花费了约 40% 的时钟下面(剩下的是范围缩小+测试工具)。但是,我无法理解 VTune 呈现给我的微架构指标:
以下是内联的相应 C++ 代码:
void stableSinCosApproximation(double x, double* sinApprox, double* cosApprox)
{
double x2 = x * x;
*sinApprox = x * (sinCoeff[7] + x2 * (sinCoeff[6] + x2 * (sinCoeff[5] + x2 * (sinCoeff[4] + x2 * (sinCoeff[3] + x2 * (sinCoeff[2] + x2 * (sinCoeff[1] + x2 * sinCoeff[0])))))));
*cosApprox = (cosCoeff[7] + x2 * (cosCoeff[6] + x2 * (cosCoeff[5] + x2 * (cosCoeff[4] + x2 * (cosCoeff[3] + x2 * (cosCoeff[2] + x2 * (cosCoeff[1] + x2 * cosCoeff[0])))))));
}
显然,汇编列表只有一个连续的指令块。没有跳转(也没有跳转目标),根本没有分支或条件执行。然而,这里有多个指标,我无法通过 VTune 的内置或在线帮助提供的信息来理解它们的值。
具体问题:
代码的后半部分几乎没有归属、时钟和所有内容。为什么?
上半年CPI不断攀升。好的,也许这点和前一点是由于归因出了问题,但我不明白。
指标表明存在不好的猜测。但是在扩展该列时,它既没有显示分支错误预测,也没有显示机器清除:
这应该告诉我什么?CPU在这里推测的容量是多少?
抢先注意事项:
重新实现这一点的目的是保证跨多个平台(来自同一个二进制文件)的一致性。内置的 sin/cos 函数可能会因机器之间的几个 ULP 而异,这可能会破坏结果的可重复性。
是的,我知道 FMA,但并不是每个必须运行这个(单个)二进制文件的平台都提供它们。目前我不打算进行运行时调度。