【发布时间】:2015-12-22 15:37:08
【问题描述】:
我正在尝试学习 OpenMP,并想学习使用 OpenMP 进行加速。为此,我编写了如下小程序:
#include <vector>
#include <cmath>
int main() {
static const unsigned int testDataSize = 1 << 28;
std::vector<double> a (testDataSize), b (testDataSize);
for (int i = 0; i < testDataSize; ++i) {
a [i] = static_cast<double> (23 ^ i) / 1000.0;
}
b.resize(testDataSize);
#pragma omp parallel for
for (int i = 0; i < testDataSize; ++i) {
b [i] = std::pow(a[i], 3) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 5) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 7) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 9) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 11) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 13) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 15) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 17) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 19) * std::exp(-a[i] * a[i]);
b [i] += std::pow(a[i], 21) * std::exp(-a[i] * a[i]);
}
return 0;
}
我编译了上面的代码,不管有没有 -std=c++11 指令。我注意到的是,当我使用 -std=c++11 指令时,我的代码运行速度比不使用它慢了大约 8 倍。我在 Linux Debian 系统上使用 -O3 和 gcc 版本 4.9.2。此外,当我比较不使用 OpenMP 的执行时间时,我确实注意到速度差异。因此,在我看来,-std=c++11 存在问题,而不是 OpenMP。
详细来说,我获得了以下执行时间(使用 Linux time 命令测量)
使用 OpenMP 和 -std=c++11 编译: 35.262s
仅使用 OpenMP 编译: 5.875s
仅使用 -std=c++11 编译: 2m12
没有 OpenMP 和 -std=c++11 的编译: 23.757s
使用-std=c++11时执行时间慢很多的原因是什么?
非常感谢任何帮助或建议!
我已经标记了以我的拙见为最佳答案的内容。在跟进 oLen 的回答时,我制作了自己的 pow(double, int) 函数,如下所示:
double my_pow(double base, int exp) {
double result = 1.0;
while (exp) {
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
我不确定这是否是计算某个基数的整数幂的最有效方法,但是使用此函数在使用或不使用 std=c++11 进行编译时,在计算效率方面我得到完全相同的结果完全符合 oLen 的回答。
【问题讨论】:
-
尝试把它扔到 Godbot 并比较生成的程序集?
-
您的问题是什么? “为什么 c++11 这么慢?”。您正在使用哪些选项?大会是什么样子的?
-
这是一个程序,不是脚本。 -
@erip:确实;感谢您的更正。我已将上述问题中的脚本更改为程序。