启用矢量化后结果(略有)不同

Results (slightly) different after vectorization is enabled

我们的一个软件正在使用 Eigen (3.2.5) 执行一些 matric/vector 相关计算。该软件在这方面经过精心开发,首先禁用所有选项和优化(包括使用 -DEIGEN_DONT_VECTORIZE),然后设置准确性测试。

由于我们现在对更快的数值吞吐量感兴趣,我们已经开始在 Eigen 中启用矢量化。但是,我们注意到,我们的一项测试现在给出的输出略有不同:与参考实现的差异约为 1e-4,而之前为 1e-5

我们将放宽此测试中的精度(因为我们并不真正了解参考数据的准确性,并且我们有另一个包含合成数据的测试用例,我们有一个精确的解决方案和仍然通过),但出于好奇:这种变化的合理原因是什么?

如果相关,此计算涉及欧几里德规范。

这在意料之中,因为当您启用矢量化时,浮点运算不会以完全相同的顺序执行。这通常发生在涉及归约的表达式中,例如总和、范数、矩阵乘积等。例如,让我们考虑以下简单的总和:

float s = 0;
for(int i=0;i<n;i++)
  s += v[i];

矢量化版本可能类似于(伪代码):

Packet ps = {0,0,0,0};
for(int i=0;i<n;i+=4)
  ps += load_packet(&v[i]);
float s = ps[0]+ps[1]+ps[2]+ps[3];

由于舍入误差,每个版本将return一个不同的值。在 Eigen 中,这方面更加棘手,因为缩减是以最大化指令流水线的方式实现的。