【发布时间】:2019-02-11 03:43:18
【问题描述】:
我从用于 Pi 逼近的 Chudnovsky 公式中得到了这段代码,我想做得越来越快。但我对如何处理 GPU 没有经验或想法。如何让这段代码在 GPU Nvidea 970M 上运行?它在 C++ 上。有一些简单的库可以做到吗?使用我的处理器,它运行大约 3~4 秒...
#include <iostream>
#include <windows>
#include <iomanip>
#include <cmath>
double fac(double num) {
double result = 1.0;
for (double i=2.0; i<num; i++)
result *= i;
return result;
}
int main() {
using namespace std;
double pi=0.0;
for (double k = 0.0; k < 10.0; k++) {
pi += (pow(-1.0,k) * fac(6.0 * k) * (13591409.0 + (545140134.0 * k)))
/ (fac(3.0 * k) * pow(fac(k), 3.0) * pow(640320.0, 3.0 * k + 3.0/2.0));
}
pi *= 12.0;
cout << setprecision(100000000) << 1.0 / pi << endl;
system("Pause");
return 0;
}
【问题讨论】:
-
要利用显卡上的多个核心,您需要将其拆分为可以委托给不同核心的部分;想想多线程。比如你可以把算法分成两个线程,一个线程计算
k的偶数,另一个线程计算k的奇数。main程序可以在线程完成后将这两个加在一起。 -
您可以通过保持 3 个 running 阶乘值来加速您的程序。每个阶乘值将乘以
k的下一个值(而不是从 1.0 重新开始阶乘计算)。 -
另一种优化是计算
fac(k),放入一个临时变量中并乘以3次:double m = fac(k); double power3 = m * m * m;。 -
根据我的测试,这段代码中的所有时间都花在了
cout << setprecision(100000000)...语句中。用更合理的setprecision(40)替换它(尽管double最多只能给出10-15 位的精度),执行时间会下降到大约0(~1 毫秒)。因此,所提供的答案中提出的优化都没有产生任何明显的差异。 -
为了好玩,请尝试运行以下代码:
#include <iostream> #include <iomanip> using namespace std; int main() { double pi=1.0/3.0; cout << setprecision(100000000) << pi << endl; return 0;}记下输出以及执行时间。