【GPU】Nvidia CUDA 编程高级教程——利用蒙特卡罗法求解近似值(MPI方法)
创始人
2024-02-01 23:44:35

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持!
博主链接

本人就职于国际知名终端厂商,负责modem芯片研发。
在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。


博客内容主要围绕:
       5G/6G协议讲解
       算力网络讲解(云计算,边缘计算,端计算)
       高级C语言讲解
       Rust语言讲解



利用蒙特卡罗法求解 𝜋 的近似值(MPI方法)

在这里插入图片描述

MPI

在单一程序中管理所有设备可能比较麻烦。这类工作通常看来就像我们目前所做的那样,对所有的可用设备进行循环,每次循环执行相同的操作(例如启动核函数)。使用 MPI(消息传递接口)可以大大简化程序。使用 MPI 时,我们独立多次启动相同的程序(单程序多数据范例)。在最常见的使用情况下,我们会在您的服务器中启动尽可能多的独立进程副本,并且每个副本只使用一个 GPU。
请添加图片描述

MPI Rank (成员编号)

每个独立进程都有一个唯一数字标识符与之相关联(称为它的 rank),并可提供信息,显示运行中的总进程数量。我们可以通过编程方式使用MPI_Comm_rank()来获取每个进程的rank,以及使用MPI_Comm_size()来获取进程的数量。有了这些信息,我们可以让每个成员做出独立的处理决策(同时仍然只使用源代码的一个副本)。例如,我们可以用cudaSetDevice()把 GPU(任意)设置为等于 MPI rank(假设成员的数量最多与 GPU 数量持平)。

有了 MPI,每个成员都可以直接独立地执行它的 N / number_of_gpus 次计算,然后对计算结果求和。这确实是使用 MPI 编写这类程序的最常见方法。

使用MPI

以下是在代码中使用 MPI 的一些详细信息。

初始化和结束MPI
必须在 MPI 程序的开头优先初始化 MPI,并在末尾结束使用MPI。

// Initialize MPI
MPI_Init(&argc, &argv);
...
// Finalize MPI
MPI_Finalize();

获取成员编号(rank)和成员数
得到成员编号(rank)和成员的总数。

int rank, num_ranks;// MPI_COMM_WORLD 意味着我们想要包含所有进程。
// 在 MPI 中,可以创建只包含某些成员的“通信器”。
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_ranks);

将 GPU 与 MPI 成员关联
我们为每个成员选择一个 GPU。

// 每个成员(任意)选择与其成员号 rank 相对应的 GPU
int dev = rank;
cudaSetDevice(dev);

收集结果
在我们的程序中,我们将对所有成员的结果进行求和(归约),并将结果存储在某个成员中,该成员将执行最终计算并打印结果。按照惯例,这是 0 号成员 rank 0(通常称为“根”处理器)。

对于此类归约,我们将使用 MPI_Reduce,它指定需要归约的数据的位置(hits)、进行归约后的结果的位置(total_hits)、归约的项目数量(1)、归约的数据类型(MPI_INT)、归约要执行的操作(MPI_SUM)、存储结果的成员(root),以及哪些进程参与通信(MPI_COMM_WORLD)。

// 将所有成员的结果累加到第 0 号成员的结果中
int* total_hits;
total_hits = (int*) malloc(sizeof(int));int root = 0;
MPI_Reduce(hits, total_hits, 1, MPI_INT, MPI_SUM, root, MPI_COMM_WORLD);if (rank == root) {// 计算 pi 的最终值并打印结果...
}

使用例子

#include 
#include #include #define N 1024*1024__global__ void calculate_pi(int* hits, int device) {int idx = threadIdx.x + blockIdx.x * blockDim.x;// 初始化随机数状态(网格中的每个线程不得重复)int seed = device;int offset = 0;curandState_t curand_state;curand_init(seed, idx, offset, &curand_state);// 在 (0.0, 1.0] 内生成随机坐标float x = curand_uniform(&curand_state);float y = curand_uniform(&curand_state);// 如果这一点在圈内,增加点击计数器if (x * x + y * y <= 1.0f) {atomicAdd(hits, 1);}
}int main(int argc, char** argv) {// 初始化 MPIMPI_Init(&argc, &argv);// 获取我们的rank和rank总数// MPI_COMM_WORLD 意味着我们想要包含所有进程// (可以在 MPI 中创建仅// 包含某些rank的“通信器”)。int rank, num_ranks;MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &num_ranks);// 确保我们的rank个数不超过 GPU 数量int device_count;cudaGetDeviceCount(&device_count);if (num_ranks > device_count) {std::cout << "Error: more MPI ranks than GPUs" << std::endl;return -1;}// 每个rank(任意)选择与其rank对应的 GPUint dev = rank;cudaSetDevice(dev);// 分配主机和设备值int* hits;hits = (int*) malloc(sizeof(int));int* d_hits;cudaMalloc((void**) &d_hits, sizeof(int));// 初始化点击次数并复制到设备*hits = 0;cudaMemcpy(d_hits, hits, sizeof(int), cudaMemcpyHostToDevice);// 启动核函数进行计算int threads_per_block = 256;int blocks = (N / device_count + threads_per_block - 1) / threads_per_block;calculate_pi<<>>(d_hits, dev);cudaDeviceSynchronize();// 将最终结果复制回主机cudaMemcpy(hits, d_hits, sizeof(int), cudaMemcpyDeviceToHost);// 将所有rank的结果累加到 rank 0 的结果中int* total_hits;total_hits = (int*) malloc(sizeof(int));int root = 0;MPI_Reduce(hits, total_hits, 1, MPI_INT, MPI_SUM, root, MPI_COMM_WORLD);if (rank == root) {// 计算 pi 的最终值float pi_est = (float) *total_hits / (float) (N) * 4.0f;// 打印结果std::cout << "Estimated value of pi = " << pi_est << std::endl;std::cout << "Error = " << std::abs((M_PI - pi_est) / pi_est) << std::endl;}// 清理free(hits);cudaFree(d_hits);// 最终确定 MPIMPI_Finalize();return 0;
}


在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...