多GPU设备处理点积示例

多GPU设备处理点积示例,项目打包下载

  1 /*
  2 * Copyright 1993-2010 NVIDIA Corporation.  All rights reserved.
  3 *
  4 * NVIDIA Corporation and its licensors retain all intellectual property and
  5 * proprietary rights in and to this software and related documentation.
  6 * Any use, reproduction, disclosure, or distribution of this software
  7 * and related documentation without an express license agreement from
  8 * NVIDIA Corporation is strictly prohibited.
  9 *
 10 * Please refer to the applicable NVIDIA end user license agreement (EULA)
 11 * associated with this source code for terms and conditions that govern
 12 * your use of this NVIDIA software.
 13 *
 14 */
 15
 16
 17 #include "../common/book.h"
 18 #include "cuda.h"
 19 #include "device_launch_parameters.h"
 20 #include "device_functions.h"
 21 #include "cuda_runtime.h"
 22
 23 #define imin(a,b) (a<b?a:b)
 24
 25 #define     N    (33*1024*1024)
 26 const int threadsPerBlock = 256;
 27 const int blocksPerGrid =
 28 imin(32, (N / 2 + threadsPerBlock - 1) / threadsPerBlock);
 29
 30
 31 __global__ void dot(int size, float *a, float *b, float *c) {
 32     __shared__ float cache[threadsPerBlock];
 33     int tid = threadIdx.x + blockIdx.x * blockDim.x;
 34     int cacheIndex = threadIdx.x;
 35
 36     float   temp = 0;
 37     while (tid < size) {
 38         temp += a[tid] * b[tid];
 39         tid += blockDim.x * gridDim.x;
 40     }
 41
 42     // set the cache values
 43     cache[cacheIndex] = temp;
 44
 45     // synchronize threads in this block
 46     __syncthreads();
 47
 48     //块内归约
 49     int i = blockDim.x / 2;
 50     while (i != 0) {
 51         if (cacheIndex < i)
 52             cache[cacheIndex] += cache[cacheIndex + i];
 53         __syncthreads();
 54         i /= 2;
 55     }
 56
 57     if (cacheIndex == 0)
 58         c[blockIdx.x] = cache[0];
 59 }
 60
 61
 62 struct DataStruct {
 63     int     deviceID;
 64     int     size;
 65     float   *a;
 66     float   *b;
 67     float   returnValue;
 68 };
 69
 70 unsigned WINAPI routine(void *pvoidData)
 71 //void* routine(void *pvoidData)
 72 {
 73     DataStruct  *data = (DataStruct*)pvoidData;
 74     HANDLE_ERROR(cudaSetDevice(data->deviceID));
 75
 76     int     size = data->size;
 77     float   *a, *b, c, *partial_c;
 78     float   *dev_a, *dev_b, *dev_partial_c;
 79
 80     // allocate memory on the CPU side
 81     a = data->a;
 82     b = data->b;
 83     partial_c = (float*)malloc(blocksPerGrid*sizeof(float));
 84
 85     // allocate the memory on the GPU
 86     HANDLE_ERROR(cudaMalloc((void**)&dev_a,
 87         size*sizeof(float)));
 88     HANDLE_ERROR(cudaMalloc((void**)&dev_b,
 89         size*sizeof(float)));
 90     HANDLE_ERROR(cudaMalloc((void**)&dev_partial_c,
 91         blocksPerGrid*sizeof(float)));
 92
 93     // copy the arrays ‘a‘ and ‘b‘ to the GPU
 94     HANDLE_ERROR(cudaMemcpy(dev_a, a, size*sizeof(float),
 95         cudaMemcpyHostToDevice));
 96     HANDLE_ERROR(cudaMemcpy(dev_b, b, size*sizeof(float),
 97         cudaMemcpyHostToDevice));
 98
 99     dot <<<blocksPerGrid, threadsPerBlock >>>(size, dev_a, dev_b,
100         dev_partial_c);
101     // copy the array ‘c‘ back from the GPU to the CPU
102     HANDLE_ERROR(cudaMemcpy(partial_c, dev_partial_c,
103         blocksPerGrid*sizeof(float),
104         cudaMemcpyDeviceToHost));
105
106     // finish up on the CPU side
107     c = 0;
108     for (int i = 0; i<blocksPerGrid; i++) {
109         c += partial_c[i];
110     }
111
112     HANDLE_ERROR(cudaFree(dev_a));
113     HANDLE_ERROR(cudaFree(dev_b));
114     HANDLE_ERROR(cudaFree(dev_partial_c));
115
116     // free memory on the CPU side
117     free(partial_c);
118
119     data->returnValue = c;
120     return 0;
121 }
122
123
124 int main(void) {
125     int deviceCount;
126     HANDLE_ERROR(cudaGetDeviceCount(&deviceCount));
127     //要求两个设备
128     if (deviceCount < 2) {
129         printf("We need at least two compute 1.0 or greater "
130             "devices, but only found %d\n", deviceCount);
131         return 0;
132     }
133
134     float   *a = (float*)malloc(sizeof(float)* N);
135     HANDLE_NULL(a);
136     float   *b = (float*)malloc(sizeof(float)* N);
137     HANDLE_NULL(b);
138
139     // fill in the host memory with data
140     for (int i = 0; i<N; i++) {
141         a[i] = i;
142         b[i] = i * 2;
143     }
144
145     /*
146     为多线程做准备
147     每个DateStruct都为数据集大小的一半
148     */
149     DataStruct  data[2];
150     data[0].deviceID = 0;
151     data[0].size = N / 2;
152     data[0].a = a;
153     data[0].b = b;
154
155     data[1].deviceID = 1;
156     data[1].size = N / 2;
157     data[1].a = a + N / 2;
158     data[1].b = b + N / 2;
159
160     CUTThread   thread = start_thread(routine, &(data[0]));
161     routine(&(data[1]));
162     end_thread(thread);
163
164
165     // free memory on the CPU side
166     free(a);
167     free(b);
168
169     printf("Value calculated:  %f\n",
170         data[0].returnValue + data[1].returnValue);
171
172     return 0;
173 }
时间: 2024-10-09 17:49:53

多GPU设备处理点积示例的相关文章

tensorflow中使用tf.ConfigProto()配置Session运行参数&amp;&amp;GPU设备指定

1. 使用tf.ConfigProto()配置Session运行参数 记录设备指派情况:tf.ConfigProto(log_device_placement=True) 自动选择运行设备: tf.ConfigProto(allow_soft_placement=True) 限制GPU资源使用: (1)动态申请显存 config = tf.ConfigProto() config.gpu_options.allow_growth = True session = tf.Session(confi

OpenStack 企业私有云的几个需求(1):Nova 虚机支持 GPU

本系列会介绍OpenStack 企业私有云的几个需求: GPU 支持 自动扩展(Auto-scaling)支持 混合云(Hybrid cloud)支持 物理机(Bare metal)支持 CDN 支持 企业负载均衡器(F5)支持 大规模扩展性(100个计算节点)支持 商业SDN控制器支持 内容比较多,很多东西也没有确定的内容.想到哪就写到哪吧.先从 GPU 支持开始. 1. 基础知识 1.1 VGA(图像显示卡),Graphics Card(图形加速卡),Video Card(视频加速卡),3D

《GPU高性能编程CUDA实战》中代码整理

CUDA架构专门为GPU计算设计了一种全新的模块,目的是减轻早期GPU计算中存在的一些限制,而正是这些限制使得之前的GPU在通用计算中没有得到广泛的应用. 使用CUDA C来编写代码的前提条件包括:(1).支持CUDA的图形处理器,即由NVIDIA推出的GPU显卡,要求显存超过256MB:(2).NVIDIA设备驱动程序,用于实现应用程序与支持CUDA的硬件之间的通信,确保安装最新的驱动程序,注意选择与开发环境相符的图形卡和操作系统:(3).CUDA开发工具箱即CUDA Toolkit,此工具箱

Hadoop 3.1.1 - Yarn - 使用 GPU

在 Yarn 上使用 GPU 前提 目前,Yarn 只支持 Nvidia GPU. YARN NodeManager 所在机器必须预先安装了 Nvidia 驱动器. 如果使用 Docker 作为容器的运行时上下文,需要安装 nvidia-docker 1.0(这是 Yarn 当前所能支持的版本). 配置 GPU 调度 在 resource-types.xml,添加如下配置 <configuration> <property> <name>yarn.resource-ty

【GPU加速系列】PyCUDA(一):上手简单操作

PyCUDA 可以通过 Python 访问 Navidia 的 CUDA 并行计算 API. 具体介绍和安装可以参考 PyCUDA 官网文档和 pycuda PyPI. 本文涵盖的内容有: 通过 PyCUDA 查询 GPU 信息. NumPy array 和 gpuarray 之间的相互转换. 使用 gpuarray 进行基本的运算. 使用 ElementwiseKernel 进行按元素的运算. 使用 InclusiveScanKernel 和 ReductionKernel 的 reduce

[spring 并行5]GPU

GPU篇 1 准备 需要有支持CUDA的Nvidia显卡 linux查看显卡信息:lspci | grep -i vga 使用nvidia显卡可以这样查看:lspci | grep -i nvidia 上一个命令可以得到类似"03.00.0"的显卡代号,查看详细信息:lspic -v -s 03.00.0 查看显卡使用情况(nvidia专用):nvidia-smi 持续周期性输出使用情况(1秒1次):watch -n 1 nvidia-smi 需要安装pycuda(linux安装:ap

编译GDAL支持OpenCL使用GPU加速

前言 GDAL库中提供的gdalwarp支持各种高性能的图像重采样算法,图像重采样算法广泛应用于图像校正,重投影,裁切,镶嵌等算法中,而且对于这些算法来说,计算坐标变换的运算量是相当少的,绝大部分运算量都在图像的重采样算法中,尤其是三次卷积采样以及更高级的重采样算法来说,运算量会成倍的增加,所以提升这些算法的处理效率优先是提高重采样的效率.由于GPU的多核心使得目前对于GPU的并行处理非常热,同时也能大幅度的提升处理速度.基于上述原因,GDALWARP也提供了基于OPENCL的GPU加速,之前在

一 GPU 编程技术的发展历程及现状

前言 本文通过介绍 GPU 编程技术的发展历程,让大家初步地了解 GPU 编程,走进 GPU 编程的世界. 冯诺依曼计算机架构的瓶颈 曾经,几乎所有的处理器都是以冯诺依曼计算机架构为基础工作的. 该系统架构简单来说就是处理器从存储器中不断取指,解码,执行. 但如今,这种系统架构遇到了瓶颈:内存的读写速度已经跟不上 CPU 的时钟频率了.具有此特征的系统被称为内存受限型系统,目前的绝大多数计算机系统都属于此类型. 为了解决这个问题,传统的解决方案是使用缓存技术.通过给 CPU 设立多级缓存,能够大

matlab GPU 操作

从Matlab2013版本开始,matlab将可以直接调用gpu进行并行计算,而不再需要安装GPUmat库.这一改动的好处是原有的matlab内置函数都可以直接运用,只要数据格式是gpuArray格式的,那么计算过程会自动的调用GPU进行计算,不可谓不方便. 具体操作起来,只要知道下面几个函数就可以像编写简单的m文件一样,进行matlab的GPU编程: 1.GPU设备确认函数 1)n=gpuDeviceCount  %返回设备上的GPU数目 2)gpuDevice         %选择GPU设