C++ 制作C++;在GPU Nvidia 970M CUDA'上并行运行的Pi近似;s
我从Chudnovsky Pi近似公式中得到了这段代码,我想做得越来越快。但是我没有经验也不知道如何处理GPU。如何使此代码在GPU NVM上运行?它是C++的。有什么简单的办法吗?用我的处理器运行大约3~4秒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 =
#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