C++ 制作C++;在GPU Nvidia 970M CUDA'上并行运行的Pi近似;s

C++ 制作C++;在GPU Nvidia 970M CUDA'上并行运行的Pi近似;s,c++,cuda,gpu,nvidia,pi,C++,Cuda,Gpu,Nvidia,Pi,我从Chudnovsky Pi近似公式中得到了这段代码,我想做得越来越快。但是我没有经验也不知道如何处理GPU。如何使此代码在GPU NVM上运行?它是C++的。有什么简单的办法吗?用我的处理器运行大约3~4秒 #include <iostream> #include <windows> #include <iomanip> #include <cmath> double fac(double num) { double result =

我从Chudnovsky Pi近似公式中得到了这段代码,我想做得越来越快。但是我没有经验也不知道如何处理GPU。如何使此代码在GPU NVM上运行?它是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;
}
#包括
#包括
#包括
#包括
双fac(双数值){
双结果=1.0;

对于(double i=2.0;i),在授权给具有多个核的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个不同的阶乘变量,并在
循环中更新它们的值

运行
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++并行编程”,了解如何在您的平台上使用并行处理来运行程序,或者在internet上搜索“c++使用gpu多核”


您希望每个核心接收的工作量比设置核心的开销花费更多的时间。

要利用图形卡上的多个核心,您需要将其分成若干部分,可以委托给不同的核心;考虑多线程。例如,您可以将算法分为两个线程s、 一个线程计算
k
的偶数值,另一个线程计算
k
的奇数值。
main
程序可以在线程完成后将这两个值相加。您可以通过保持3个运行的阶乘值来加速程序。每个阶乘值将乘以
k
的下一个值>(而不是从1.0重新启动阶乘计算)。另一种优化是计算
fac(k)
,将其放入一个临时变量中并将其自身相乘3次:
double m=fac(k);double power3=m*m*m;
。根据我的测试,这段代码中的所有时间都花在
cout上。为了好玩,试着运行这段代码:
#include#include使用名称空间std;int main(){double pi=1.0/3.0;cout