使 C++ Pi 近似在 GPU Nvidia 970M CUDA 上的 Paralell 中运行
Making C++ Pi approximation running in Paralell on GPU Nvidia 970M CUDA's
我从 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多核"。
您希望每个内核接收的工作量比设置内核的开销消耗更多的时间。
- 编译时未启用intel oneApi CUDA支持
- 在cuda线程之间共享大量常量数据
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- CUDA内核和数学函数的显式命名空间
- CUDA:统一内存和指针地址的更改
- 调试 CUDA MMU 故障
- 使用 CUDA 和纹理进行图像减法
- 将 2D 推力::d evice_vector 复矩阵传递给 CUDA 内核函数
- 编译 CUDA 与数学函数的叮当
- 为什么 CUDA 不会导致C++代码加速?
- 如何防止 CUDA-GDB 中的<优化输出>值
- 通过Python Distutils(用于Python C扩展)使用可重定位的设备代码编译CUDA代码
- CUDA三角函数中的数学保证
- CUDA 使用共享内存平铺 3D 卷积实现
- CUDA:cudaMallocManage处理退出吗?
- Opencv 加速与 CUDA 在 C++.
- Cuda:具有位集数组的 XOR 单位集
- 用于构建 cuda .so 文件(共享库)的生成文件
- 使 C++ Pi 近似在 GPU Nvidia 970M CUDA 上的 Paralell 中运行