使 C++ Pi 近似在 GPU Nvidia 970M CUDA 上的 Paralell 中运行

Making C++ Pi approximation running in Paralell on GPU Nvidia 970M CUDA's

本文关键字:CUDA 970M 上的 Paralell 运行 Nvidia GPU Pi C++      更新时间:2023-10-16

我从 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;
}

在委托给具有多个内核的 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  |              |              |  
+-----+--------------+--------------+  

看看你是否注意到任何模式。
还要垂直重写赋值,看看是否可以通过分解来简化。

利用 GPU 内核

将计算优化为运行或迭代方法后,可以委托给多个内核。

第一步是弄清楚如何将工作划分为可以并行运行的各个部分。

将计算分成三部分并运行(在一个内核上(。 验证正确性。

下一步是研究"C ++并行编程"以获取有关如何在您的平台上使用并行处理运行程序的说明,或者在互联网上搜索"C ++使用GPU多核"。

您希望每个内核接收的工作量比设置内核的开销消耗更多的时间。