`
暴风雪
  • 浏览: 388735 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[CUDA]CUDA C并行编程

 
阅读更多

CUDA将GPU称为设备,将CPU称为主机,一般的计算方式是将数据从内存拷贝进GPU内存(显存),通过GPU计算再拷回内存中。

下面的代码是一个经典的通过GPU进行的向量加法运算

代码来自http://bbezxcy.iteye.com/blog/2220819

#include<cuda_runtime.h>
#include<windows.h>
#include<iostream>
using namespace std;
const int nMax = 30000;
__global__ void addKernel(float *aaa,float *bbb, float *ccc)
{
	//int i = blockIdx.x;
	int i = threadIdx.x + blockIdx.x*blockDim.x;
	ccc[i] = 0;
	if (i < nMax)for (int j = 0; j < 500; j++)ccc[i] += aaa[i] * bbb[i];
}
void add(float *a, float *b,float *c,int i){
	for (int j = 0; j<500; j++) c[i] += a[i] * b[i];
}
int main(){
	float a[nMax], b[nMax], c[nMax];
	float *devA, *devB, *devC;
	clock_t startT, endT;
	for (int i = 0; i < nMax; i++){
		a[i] = i*1.010923;
		b[i] = 2.13*i;
	}
	startT = clock();
	cudaMalloc((void**)&devA, nMax*sizeof(float));
	cudaMalloc((void**)&devB, nMax*sizeof(float));
	cudaMalloc((void**)&devC, nMax*sizeof(float));
	endT = clock();
	cout << "分配设备空间耗时 " << endT - startT << "ms"<<endl;


	startT = clock();
	cudaMemcpy(devA, a,nMax*sizeof(float),cudaMemcpyHostToDevice);
	cudaMemcpy(devB, b, nMax*sizeof(float), cudaMemcpyHostToDevice);
	endT = clock();
	cout << "数据从主机写入设备耗时 " << endT - startT << "ms" << endl;

	startT = clock();

	cudaEvent_t start1;
	cudaEventCreate(&start1);
	cudaEvent_t stop1;
	cudaEventCreate(&stop1);
	cudaEventRecord(start1, NULL);

	addKernel<<<60,501>>>(devA, devB, devC);

	cudaEventRecord(stop1, NULL);
	cudaEventSynchronize(stop1);
	float msecTotal1 = 0.0f;
	cudaEventElapsedTime(&msecTotal1, start1, stop1);
	//cout << msecTotal1 << "ddd" << endl;
	endT = clock();
	cout << "GPU计算耗时 " << msecTotal1 << "ms" << endl;

	startT = clock();
	cudaMemcpy(c, devC, nMax*sizeof(float), cudaMemcpyDeviceToHost);
	endT = clock();
	cout << "数据从设备写入主机耗时 " << endT - startT << "ms" << endl;

	cout <<"GPU计算结果 "<< c[nMax - 1] << endl;
	for (int i = 0; i < nMax; i++){
		a[i] = i*1.010923;
		b[i] = 2.13*i;
		c[i] = 0;
	}
	startT = clock();
	for (int i = 0; i < nMax; i++){
		add(a, b, c, i);
	}
	endT = clock();
	cout << "CPU计算耗时 " << endT - startT << "ms" << endl;
	cout << "CPU计算结果 " << c[nMax - 1] << endl;

        //释放在设备上分配的空间
	cudaFree(devA);
	cudaFree(devB);
	cudaFree(devC);
	cin >> a[0];
	return 0;
}

 上面的代码中使用了一些通用模式

1,调用cudaMalloc();这个函数在设备(GPU)上分配内存。一般来说为了避免内存泄漏计算完成之后需要通过cudaFree来释放内存空间。

2,cudaMemcpy(devA, a,nMax*sizeof(float),cudaMemcpyHostToDevice);这个函数用来处理主机和设备之间的数据拷贝。最后的参数cudaMemcpyHostToDevice代码是从主机拷贝去设备,如果需要从设备拷贝数据到主机需要将这个参数改为cudaMemcpyDeviceToHost。

3,在定义函数的时候在前面加上__global__,则这个函数就是一个在主机上调用,在设备上运行的函数。在上面的代码里,调用__global__函数代码是

addKernel<<<60,1>>>(devA, devB, devC);

这里的<<<60,501>>>的意思是,调用函数的时候,开出60个线程格,每个线程格包含501个线程。在global函数中通过代码int i = threadIdx.x + blockIdx.x*blockDim.x;得到当前线程是第几个线程。

 

在调用global函数的时候,我们可以通过dim3类型变量修改调用函数的方式
例如dim3 grid(10,10);addKernel<<<grid,501>>>(devA, devB, devC);这样就可以把按照一维排列的线程块改为在二维空间内排布。函数内可以通过一下代码得到当前线程的标号
int x = blockIdx.x;
int y = blockIdx.y;
int threadId = x + y *gridDim.x;
 

CUDA为我们内建了一些变量用于访问线程格、线程块的尺寸和索引等信息,它们是:

      1. gridDim:代表线程格(grid)的尺寸,gridDim.x为x轴尺寸,gridDim.y、gridDim.z类似。拿上图来说,它的gridDim.x = 3,gridDim.y = 2,gridDim.z = 1。

      2. blockIdx:代表线程块(block)在线程格(grid)中的索引值,拿上图来说,Block(1,1)的索引值为:blockIdx.x = 1,blockIdx.y = 1。

      3. blockDim:代表线程块(block)的尺寸,blockDIm.x为x轴尺寸,其它依此类推。拿上图来说,注意到Block(1,1)包含了4 * 3个线程,因此blockDim.x = 4, blockDim.y = 3。

 

      4. threadIdx:线程索引,前面章节已经详细探讨过了,这里不再赘述。

1
3
分享到:
评论

相关推荐

    CUDA高性能计算并行编程[整理].pdf

    CUDA高性能计算并行编程 CUDA(Compute Unified Device Architecture)是一种由 NVIDIA 公司开发的通用并行计算架构,允许开发者在 NVIDIA 图形处理单元(GPU)上进行通用计算。CUDA 提供了一个基于 C 语言的编程...

    CUDA并行程序设计 GPU编程指南,cuda并行程序设计gpu编程指南pdf,C,C++

    CUDA并行程序设计GPU编程指南是针对这一技术的专业参考资料,旨在帮助程序员深入理解和掌握CUDA编程。 CUDA的核心概念包括以下几点: 1. **CUDA核心(CUDA Cores)**:GPU中的运算单元,执行线程块内的线程。这些...

    CUDA编程 并行编程

    CUDA编程是一种专门针对NVIDIA图形处理单元(GPU)的并行编程技术,它允许开发者使用C、C++以及其他语言来开发可以在GPU上运行的软件。GPU内部拥有成百上千个小核心,能够并行处理大量的数据,尤其适合处理那些可以...

    CUDA C编程权威指南.pdf

    - **1.1.1 串行编程和并行编程** - **串行编程**:按照顺序逐条执行指令。 - **并行编程**:同时执行多条指令,利用多处理器或多核心提高效率。 - **1.1.2 并行性** - 并行性的概念及其在提高计算速度中的作用。...

    CUDA并行程序设计 GPU编程指南

    CUDA并行程序设计:GPU编程指南共分为12章。第1章从宏观上介绍流处理器演变历史。第2章详解GPU并行机制,深入理解串行与并行程序,以辩证地求解问题。第3章讲解CUDA设备及相关的硬件和体系结构,以实现优CUDA程序...

    并行编程cuda

    在早期使用CUDA这种可扩展的并行编程模型及其C语言扩展的过程中,许多复杂的程序能够通过几个易于理解的抽象概念来表达。自NVIDIA在2007年发布CUDA以来,开发者已经迅速开发了适用于广泛应用领域的可扩展并行程序,...

    Cuda C 编程指南(程润伟)

    CUDA C 编程指南是程润伟教授的著作,它主要...总之,《CUDA C 编程指南》是一本全面介绍CUDA编程的书籍,涵盖了从基础概念到高级优化的各个方面,对于想要利用GPU进行并行计算的开发者来说,是一本不可多得的参考书。

    CUDA并行程序设计GPU编程指南(包含原书代码book.h CPUBitmap.h等)

    CUDA并行程序设计是利用NVIDIA公司的CUDA技术在GPU(图形处理器)上执行计算密集型任务的一种高效方法。...通过阅读"CUDA并行程序设计 GPU编程指南",你可以深入学习这些概念,并通过实际代码示例来提升你的编程技能。

    CUDA并行程序设计 GPU编程指南-中文英文高清完整版(各500+页)

    CUDA并行程序设计 GPU编程指南-中文英文高清完整版(各500+页)

    CUDA高性能计算并行编程

    2007年6月,NVIDIA公司推出了CUDA(Compute Unified Device Architecture),CUDA不需要借助图形学API,而是采用了类C语言进行开发。同时,CUDA采用了统一处理架构,降低了编程的难度,使得NVIDIA相比AMD/ATI后来居上...

    CUDA by example (中文:GPU高性能编程CUDA实战)代码实例

    7. **CUDA并行算法设计**:书中会介绍如何将常见的计算问题转化为适合GPU并行处理的形式,如矩阵乘法、傅里叶变换、蒙特卡洛模拟等,并提供实际的代码示例。 8. **CUDA与OpenMP、MPI的结合**:CUDA可以与其他并行...

    CUDA高性能计算并行编程.zip

    CUDA并行编程的主要目标是提高计算效率,尤其是在处理大规模数据集时。 在CUDA中,GPU被视为一个可编程的设备,其核心组成部分包括流式多处理器(Streaming Multiprocessors, SM)、线程块(Thread Blocks)和线程...

    7.CUDA C编程权威指南 (1)1

    在并行计算部分,书中首先介绍了串行编程与并行编程的区别,指出并行性是提升计算效率的关键。并行性允许同时处理多个任务,尤其在现代计算机架构中,多核心和多处理器系统成为主流,使得并行计算成为可能。接着,书...

    GPU高性能编程CUDA版_CUDA并行程序设计打包下载

    CUDA并行程序设计是GPU编程的核心,通过这种技术,我们可以充分利用GPU的并行处理能力,为科学计算、机器学习、图像处理等领域带来显著的速度提升。 CUDA编程主要包括以下几个关键知识点: 1. **CUDA架构**:CUDA...

    CUDA_C_Programming_Guide.pdf

    NVIDIA CUDA是一种通用并行计算架构,它集成了GPU(图形处理单元)和CPU(中央处理单元),并提供了一个完整的并行计算平台和编程模型。CUDA可以加速深度学习、数据挖掘、科学计算等多种应用,是一种在图形处理器上...

    CUDA 高性能并行计算.pdf

    本书介绍了CUDA编程的核心知识,始于运行CUDA样例程序,快速引导读者构建自己的代码。书中配备的实践项目用以加深和巩固对CUDA编程的理解。

Global site tag (gtag.js) - Google Analytics