我从Chudnovsky公式中获得了用于Pi逼近的代码,我想越来越快地做到这一点。但是我对如何处理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;
}
答案 0 :(得分:1)
在委派具有多个内核的GPU之前,建议您首先使用一个内核优化算法。
对于每个k值,阶乘函数始终从2.0开始。计算如下:
+----+-------------------+
| 1! | 1 |
+----+-------------------+
| 2! | 1 * 2 |
+----+-------------------+
| 3! | 1 * 2 * 3 |
+----+-------------------+
| 5! | 1 * 2 * 3 * 4 * 5 |
+----+-------------------+
随着k
的值变大,这些迭代的时间加起来。
阶乘可以迭代表示为:
+----+--------+
| 1! | 1 |
+----+--------+
| 2! | 1! * 2 |
+----+--------+
| 3! | 2! * 3 |
+----+--------+
| 5! | 4! * 5 |
+----+--------+
换句话说,下一个阶乘使用先前的阶乘值并乘以k
的值。
您的main
看起来像:
int main()
{
double k_factorial = 1.0;
//...
for (/* ... */)
{
if (k > 1.0) k_factorial *= k;
//...
/ (fac(3.0 * k) * pow(k_factorial, 3.0) * pow(640320.0, 3.0 * k + 3.0/2.0));
//...
}
由于您有3个不同的阶乘:fac(3.0 * k), fac(k),
和fac(6.0 * k)
,因此可以使用3个不同的阶乘变量并在for
循环内更新它们的值。
pow
变量类似于阶乘变量,您可以为pow
函数获取运行值。
pow(-1.0, k)
可以替换为:
double pow_sign = 1.0; // pow(-1.0, 0)
//...
for (//...
{
pow_sign *= -1.0;
pi += (pow_sign * //...
此外,我们知道pow(x, 3)
与x * x * x
相同。进行替换:
pow(fac(k), 3.0)
-> factorial_k * factorial_k * factorial_k
您也可以代数简化您的赋值语句。 例如,制作一个包含以下各列的表:
+-----+--------------+--------------+
| k | fac(6.0 * k) | fac(3.0 * k) |
+-----+--------------+--------------+
| 0 | | |
+-----+--------------+--------------+
| 1 | | |
+-----+--------------+--------------+
看看您是否注意到任何图案。
还要垂直重写分配,以查看是否可以通过分解简化。
将计算优化为运行或迭代方法后,就可以委托给多个内核。
第一步是弄清楚如何将工作划分为可以并行运行的部分。
将您的计算分为三部分并运行(在一个内核上)。验证正确性。
下一步是研究“ c ++并行编程”以获取有关如何在平台上使用并行处理运行程序的说明,或者在“ c ++使用gpu多核”上搜索Internet。
您希望每个核心所花费的工作量要比设置核心所花费的时间更多。