特征表达模板比指数的手动循环慢

时间:2016-07-24 14:21:36

标签: c++ performance visual-studio-2010 eigen eigen3

我正在尝试计算数组的组件指数的总和。数组是my.cnf,因此我希望Eigen的Eigen::ArrayXd函数将优化为与手动循环相同或更好的代码。相反,我发现手动循环的速度提高了几十个百分点。 (在下面的示例中,Eigen大约为2.1秒,手动循环大约为1.6秒。)

我没有使用任何特征向量化(SSE被禁用),MKL或其他任何特殊的。这只是一个默认的Visual Studio 2010项目,在Release配置上,Eigen 3.2.9开箱即用。指定“完全优化”(/ Ox)和“赞成快速代码”(/ Ot)对结果没有影响。

我不够了解编译代码以了解正在发生的事情 - 任何人都可以建议为什么直接使用Eigen可能会更慢,以及如何哄它以产生与手动循环相同的性能?

exp

1 个答案:

答案 0 :(得分:2)

如果您定义了results.forEach,则两种方法在C ++代码方面几乎相同,循环遍历数组的每个元素。

使用EIGEN_DONT_VECTORIZE/Ox,您告诉编译器自动向量化循环。但是,由Eigen生成的循环可能比手写循环更复杂/更低效。因此性能较低。

这也取决于编译器。对于不自动向量化循环的编译器,带/Ot的Eigen与循环方法几乎相同。

EIGEN_DONT_VECTORIZE

启用特征向量化后,Eigen表现更好。

$ g++ -DEIGEN_DONT_VECTORIZE -g -O3 -DNDEBUG eigen-speed.cpp -o eigen-speed && ./eigen-speed
Array time (seconds): 1.94
Loop time (seconds): 1.93

使用自动矢量化循环的编译器,带有$ g++ -g -O3 -DNDEBUG eigen-speed.cpp -o eigen-speed && ./eigen-speed Array time (seconds): 0.63 Loop time (seconds): 1.86 的Eigen仍然类似于循环方法,但都由编译器进行矢量化。

EIGEN_DONT_VECTORIZE

但是当你启用特征向量化时,

$ icpc -DEIGEN_DONT_VECTORIZE -g -O3 -DNDEBUG eigen-speed.cpp -o eigen-speed && ./eigen-speed
Array time (seconds): 0.43
Loop time (seconds): 0.38

建议Eigen的矢量化exp()代码比编译器的自动矢量化版本更差,Eigen's SSE versionEigen's AVX version都可以。

所以你可以看到VS更像$ icpc -g -O3 -DNDEBUG eigen-speed.cpp -o eigen-speed && ./eigen-speed Array time (seconds): 0.7 Loop time (seconds): 0.36 $ icpc -mavx -g -O3 -DNDEBUG eigen-speed.cpp -o eigen-speed && ./eigen-speed Array time (seconds): 0.32 Loop time (seconds): 0.18