我正在尝试计算数组的组件指数的总和。数组是my.cnf
,因此我希望Eigen的Eigen::ArrayXd
函数将优化为与手动循环相同或更好的代码。相反,我发现手动循环的速度提高了几十个百分点。 (在下面的示例中,Eigen大约为2.1秒,手动循环大约为1.6秒。)
我没有使用任何特征向量化(SSE被禁用),MKL或其他任何特殊的。这只是一个默认的Visual Studio 2010项目,在Release配置上,Eigen 3.2.9开箱即用。指定“完全优化”(/ Ox)和“赞成快速代码”(/ Ot)对结果没有影响。
我不够了解编译代码以了解正在发生的事情 - 任何人都可以建议为什么直接使用Eigen可能会更慢,以及如何哄它以产生与手动循环相同的性能?
exp
答案 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 version和Eigen'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
。