CUDA C的并行编程
来源:互联网 发布:搬家软件哪个好 编辑:程序博客网 时间:2024/06/02 19:25
1.首先我们可以先看一下传统的CPU向量编程
#define N 10void add( int *a, int *b, int *c ) { int tid = 0; // this is CPU zero, so we start at zero while (tid < N) { c[tid] = a[tid] + b[tid]; tid += 1; // we have one CPU, so we increment by one }}int main( void ) { int a[N], b[N], c[N]; // fill the arrays 'a' and 'b' on the CPU for (int i=0; i<N; i++) { a[i] = -i; b[i] = i * i; } add( a, b, c ); // display the results for (int i=0; i<N; i++) { printf( "%d + %d = %d\n", a[i], b[i], c[i] ); } return 0;}
上面的add函数针对的是单核CPU编程,如果遇到了多核CPU,那么可以修改add函数,进而每个核可以分配不同的任务,比如说是双核CPU编程,add函数可以修改如下所示
void add( int *a, int *b, int *c ) { int tid = 0; while (tid < N) { c[tid] = a[tid] + b[tid]; tid += 2; }}void add( int *a, int *b, int *c ) { int tid = 1; while (tid < N) { c[tid] = a[tid] + b[tid]; tid += 2; }}
但是,这样的编程带来了很多缺点,比如说要多编很多的代码。这里引入GPU编程,那么add函数就可以编写成设备函数
首先,是main函数:
#define N 10int main( void ) { int a[N], b[N], c[N]; int *dev_a, *dev_b, *dev_c; // allocate the memory on the GPU HANDLE_ERROR( cudaMalloc( (void**)&dev_a, N * sizeof(int) ) ); HANDLE_ERROR( cudaMalloc( (void**)&dev_b, N * sizeof(int) ) ); HANDLE_ERROR( cudaMalloc( (void**)&dev_c, N * sizeof(int) ) ); // fill the arrays 'a' and 'b' on the CPU for (int i=0; i<N; i++) { a[i] = -i; b[i] = i * i; } // copy the arrays 'a' and 'b' to the GPU HANDLE_ERROR( cudaMemcpy( dev_a, a, N * sizeof(int), cudaMemcpyHostToDevice ) ); HANDLE_ERROR( cudaMemcpy( dev_b, b, N * sizeof(int), cudaMemcpyHostToDevice ) ); add<<<N,1>>>( dev_a, dev_b, dev_c ); // copy the array 'c' back from the GPU to the CPU HANDLE_ERROR( cudaMemcpy( c, dev_c, N * sizeof(int), cudaMemcpyDeviceToHost ) ); // display the results for (int i=0; i<N; i++) { printf( "%d + %d = %d\n", a[i], b[i], c[i] ); } // free the memory allocated on the GPU cudaFree( dev_a ); cudaFree( dev_b ); cudaFree( dev_c ); return 0;}
其次,是add功能函数:
__global__ void add( int *a, int *b, int *c ) { int tid = blockIdx.x; // handle the data at this index if (tid < N) c[tid] = a[tid] + b[tid];}
1>在设备上执行的add函数也是用C语言实现的,同时在函数的前面添加__global__
2> <<< >>>内的参数和内核自己的参数
<<<N,1 >>>内的参数用于在运行时描述如何加载内核(也就是CUDA的C函数),第一个参数是相应设备执行内核的block数。通过内置变量blockIdx可以知道目前哪个block正在运行。
为什么选用blockIdx.x?因为CUDA C设置了一组二维的block。但是注意,luanch的block数量不要超过65535,这是个上限。
3.和C函数相应的CUDA C 函数
malloc() -> cudamalloc()
free -> cudafree()
memcpy() -> cudaMemcpy() 最后一个参数指明拷贝方向,cudaMemcpyDeviceToHost;cudaMemcpyHostToDevice;cudaMemcpyDeviceToDevice
像是其他的内核函数如,cudaGetDeviceCount(&count)用于检查设备数量,cudaDeviceProp是设备信息结构,cudaGetDeviceProperties(cudaDeviceProp &,int i)用于得到第i个设备信息。
- CUDA C的并行编程
- [CUDA]CUDA C并行编程
- [CUDA学习]3. CUDA C并行编程
- CUDA学习二:CUDA C并行编程
- CUDA并行编程的一个例子
- CUDA并行编程较有用的总结
- CUDA并行编程较有用的总结
- 【CUDA并行编程之六】KNN算法的并行实现
- 【CUDA并行编程之六】KNN算法的并行实现
- CUDA并行编程入门
- CUDA的并行计算
- 并行编程1:CUDA基础
- CUDA-CODE4-并行编程-blockIDx
- CUDA-CODE5-并行编程(1)
- CUDA-CODE5-并行编程(2)
- CUDA并行编程学习心得1
- CUDA并行编程学习心得2
- 【CUDA并行编程之五】计算向量的欧式距离
- 4步教你学会使用matlab模糊控制工具箱
- 在图库Gallery3D中旋转图片,然后用蓝牙分享失败
- VC下利用ADO连接Access数据库
- c中的常量
- QSplitter在QTabWidget中使用
- CUDA C的并行编程
- 那年,那场青春繁华梦
- 检验IP地址有效性
- 腾讯电面
- Python发送Email
- 有关Oracle表分区进行(DML)维护后对索引的影响的分析
- Android应用开发揭秘(笔记) 第三章 程序设计基础
- Android开发如何利用Google Maps
- Ini文件读取类,采用C++ STL实现