我试图计算一个数组的分量指数的总和。阵列是一个Eigen::ArrayXd
,所以我期望Eigen的exp
函数将被优化为相同的代码,或更好,比手动循环。相反,我看到一个手动循环快了几十个百分点。 (在下面的例子中,Eigen大约为2.1秒,手动循环为1.6秒。)特征表达模板比指数的手动循环慢
我没有使用任何特征向量化(SSE被禁用),MKL或其他任何特殊的东西。这只是一个默认的Visual Studio 2010项目,在Release配置上,带有Eigen 3.2.9开箱即用。指定“完全优化”(/ Ox)和“优先快速代码”(/ Ot)对结果没有影响。
我没有足够的知识来查看编译代码以了解发生了什么 - 任何人都可以提出为什么直接使用Eigen可能会更慢,以及如何哄它产生与手动循环相同的性能?
#include <ctime>
#include <iostream>
#include <Eigen/Dense>
int main(int argc, char* argv[])
{
const Eigen::ArrayXd xs(Eigen::ArrayXd::Random(1000000));
Eigen::ArrayXd array_result(Eigen::ArrayXd::Zero(xs.size())), loop_result(Eigen::ArrayXd::Zero(xs.size()));
{
std::clock_t start_time = std::clock();
for (int i = 1; i <= 100; ++i) {
const double b = i; // Values not important;
array_result += exp(b * xs);
}
std::clock_t end_time = std::clock();
std::cout << "Array time (seconds): " << static_cast<double>(end_time - start_time)/CLOCKS_PER_SEC << std::endl;
}
{
std::clock_t start_time = std::clock();
for (int i = 1; i <= 100; ++i) {
const double b = i; // Values not important;
for (Eigen::ArrayXd::Index i = 0; i < xs.size(); ++i) {
loop_result[i] += exp(b * xs[i]);
}
}
std::clock_t end_time = std::clock();
std::cout << "Loop time (seconds): " << static_cast<double>(end_time - start_time)/CLOCKS_PER_SEC << std::endl;
}
system("pause");
return 0;
}
你试过'(b * xs).exp()'吗?你定义了'EIGEN_DONT_VECTORIZE'的 –
? – kangshiyin
@Avi,我尝试过'(b * xs).exp()' - 表现看起来相同。 @ kangshiyin,定义'EIGEN_DONT_VECTORIZE'似乎不会影响性能。 – GavinTruter