博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第五篇:CUDA 并行程序中的同步
阅读量:5142 次
发布时间:2019-06-13

本文共 2479 字,大约阅读时间需要 8 分钟。

前言

       在并发,多线程环境下,同步是一个很重要的环节。同步即是指进程/线程之间的执行顺序约定。

       本文将介绍如何通过共享内存机制实现块内多线程之间的同步。

       至于块之间的同步,需要使用到 global memory,代价较为高昂,目前使用的情况也不多,就先不介绍了。

块内同步函数:__syncthreads ()

       线程调用此函数后,该线程所属块中的所有线程均运行到这个调用点后才会继续往下运行。

代码示例

       使用同步思想优化之前一篇博文中提到的数组求和程序。在新的程序中,让每个块中的第一个线程将块中所有线程的运算结果都加起来,然后再存入到结果数组中。这样,结果数组的长度与块数相等 (原来是和总线程数相等),大大降低了 CPU 端程序求和的工作量以及需要传递进/出显存的数据 (代码下方如果出现红色波浪线无视之):

1 // 相关 CUDA 库  2 #include "cuda_runtime.h"  3 #include "cuda.h"  4 #include "device_launch_parameters.h"  5   6 // 此头文件包含 __syncthreads ()函数  7 #include "device_functions.h"  8   9 #include 
10 #include
11 12 using namespace std; 13 14 const int N = 100; 15 16 // 块数 17 const int BLOCK_data = 3; 18 // 各块中的线程数 19 const int THREAD_data = 10; 20 21 // CUDA初始化函数 22 bool InitCUDA() 23 { 24 int deviceCount; 25 26 // 获取显示设备数 27 cudaGetDeviceCount (&deviceCount); 28 29 if (deviceCount == 0) 30 { 31 cout << "找不到设备" << endl; 32 return EXIT_FAILURE; 33 } 34 35 int i; 36 for (i=0; i
=1) //cuda计算能力 42 { 43 break; 44 } 45 } 46 } 47 48 if (i==deviceCount) 49 { 50 cout << "找不到支持 CUDA 计算的设备" << endl; 51 return EXIT_FAILURE; 52 } 53 54 cudaSetDevice(i); // 选定使用的显示设备 55 56 return EXIT_SUCCESS; 57 } 58 59 // 此函数在主机端调用,设备端执行。 60 __global__ 61 static void Sum (int *data,int *result) 62 { 63 // 声明共享内存 (数组) 64 extern __shared__ int shared[]; 65 // 取得线程号 66 const int tid = threadIdx.x; 67 // 获得块号 68 const int bid = blockIdx.x; 69 70 shared[tid] = 0; 71 // 有点像网格计算的思路 72 for (int i=bid*THREAD_data+tid; i
>> (gpudata,result);120 121 // 在内存中为计算对象开辟空间122 int *sumArray = new int[BLOCK_data];123 // 从显存获取处理的结果124 cudaMemcpy (sumArray, result, sizeof(int)*BLOCK_data, cudaMemcpyDeviceToHost);125 126 // 释放显存127 cudaFree (gpudata); 128 cudaFree (result);129 130 // 计算 GPU 每个块计算出来和的总和131 int final_sum=0;132 for (int i=0; i

运行结果

  

  PS:矩阵元素是随机生成的

小结

  共享内存,或者说这个共享数组是 CUDA 中实现同步最常用的方法。

转载于:https://www.cnblogs.com/muchen/p/6306792.html

你可能感兴趣的文章
SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)
查看>>
kubernetes_book
查看>>
OpenFire 的安装和配置
查看>>
ZJOI2018游记Round1
查看>>
侧边栏广告和回到顶部
查看>>
https://blog.csdn.net/u012106306/article/details/80760744
查看>>
ios应用版本号设置规则
查看>>
海上孤独的帆
查看>>
error: more than one device and emulator 问题解决
查看>>
Java基础:容器
查看>>
YUV摘要格式
查看>>
【方法2】删除Map中Value反复的记录,而且仅仅保留Key最小的那条记录
查看>>
C# CheckedListBox控件的使用方法
查看>>
【HDOJ】2007平方和与立方和
查看>>
js中const,var,let区别
查看>>
SharePoint自定义程序页面部署 不用重启IIS
查看>>
2014-11-30-2333-Java-数组
查看>>
Nginx 自动补全url地址补全最后的斜线
查看>>
【SQL Server 2008 安装全过程】
查看>>
xml的解析及案例的分析和分享
查看>>