转自:http://blog.sina.com.cn/s/blog_48b9e1f90100fm56.html

CUDA的代码分成两部分,一部分在host(CPU)上运行,是普通的C代码;另一部分在device(GPU)上运行,是并行代码,称为kernel,由nvcc进行编译。

Kernel产生的所有线程成为Grid。在并行部分结束后,程序回到串行部分即到host上运行。

在CUDA中,host和device有不同的内存空间。所以在device上执行kernel时,程序员需要把host memory上的数据传送到分配的device memory上。在device执行完以后,需要把结果从device传送回host,并释放device memory。CUDA runtime system提供了API给程序员做这些事情。

Float *Md;

Int size=Width*Width*sizeof(float);

API:

cudaMalloc((void**)&Md, size)——从host code调用,为device在global memory分配内存空间。第一个参数是指向分配对象的地址,第二个参数是分配大小;

cudaFree(Md)——释放device Global Memory。

cudaMemcpy(Md, M, size, dudaMemcpyHostToDevice)——内存数据传输。四个参数分别为:指向目的数据的指针,指向源(要copy的)数据指针,要copy出的数据字节数,传输方式(host to host, host to device, device to host, device to device)

内核部分

__global__说明这个函数是一个kernel,host function可以调用这个函数产生线程

threadIdx.x线程index

一个kernel被调用时,以并行线程的grid形式执行。一个kernel创建一个grid。Grid中的线程被组织成两个层次。在最顶层,每个grid包含一个或多个thread block。Grid中的所有block有相同数目的线程。每个thread block有一个唯一的二维坐标,由CUDA的特定关键字blockIdx.x和blockIdx.y指定。所有的thread block必须以相同的方式组织,并有相同数目的thread。

Thread block:包含相互之间能够协作的线程,这些线程通过同步或者在低延迟的shared memory之间共享数据进行协作。不同block里的线程不能协作。每个thread block组织成三位的线程数组,最大线程数目为512。Block中的线程坐标是唯一的,通过三个线程id指定:threadIdx.x, threadIdx.y, threadIdx.z。不是所有的应用程序会使用thread block的三个维度。

当host code调用一个kernel时,通过参数传递来设置grid和thread block的维度。如下:

// Setup the execution configuration

dim3 dimBlock(WIDTH, WIDTH);

dim3 dimGrid(1, 1);

// Launch the device computation threads!

MatrixMulKernel<<<dimGrid, dimBlock>>>(Md, Nd, Pd);

以上是摘自David Kirk和Wen-mei Hwu的课程,讲的比较清楚。感觉CUDA编程一个比较自由的编程方式,由于是在C之上的扩展,加了一些关键字,比较容易,编程方式让人很好接受。一方面给了程序员很大的发挥空间,thread, thread block等都可以自由配置,另一方面也给程序员提出了挑战,这么大的空间中怎样编程以取得好的性能。

一个简单的矩阵乘程序

#include<stdio.h>

#include<stdlib.h>

#include<cuda.h>

//内核程序

__global__ void MatrixMulKernel(float* Md, float* Nd, float* Pd, int Width)

{

//2D Thread ID

int tx=threadIdx.x;

int ty=threadIdx.y;

printf("I'm thread: %d %d\n",tx,ty);

//Pvalue stores the Pd element that is computed by the thread

float Pvalue=0;

for(int k=0; k<Width; k++)

{

float Mdelement=Md[ty*Width+k];

float Ndelement=Nd[k*Width+tx];

Pvalue+=Mdelement*Ndelement;

printf("%f  %f   %f\n",Mdelement,Ndelement,Pvalue);

}

//Write the matrix to device memory each thread writes one element

Pd[ty*Width+tx]=Pvalue;

}

void MatrixMulOnDevice(float* M, float* N, float* P, int Width)

{

int size=Width*Width*sizeof(float);

float *Md,*Nd,*Pd;

dim3 dimBlock(Width,Width);

dim3 dimGrid(1,1);

//Load M and N to device memory

cudaMalloc((void **)&Md,size);

cudaMemcpy(Md,M,size,cudaMemcpyHostToDevice);

cudaMalloc((void **)&Nd,size);

cudaMemcpy(Nd,N,size,cudaMemcpyHostToDevice);

//for(int i=0;i<3;i++)printf("%d ",Md[i]);

//Allocate P on the device

cudaMalloc((void**)&Pd,size);

//Kernel invocation code

MatrixMulKernel<<<dimGrid,dimBlock>>>(Md,Nd,Pd,Width);

//Read P from the device

cudaMemcpy(P,Pd,size,cudaMemcpyDeviceToHost);

//Free device matrices

cudaFree(Md);cudaFree(Nd);cudaFree(Pd);

}

int main(void)

{

// Allocate and initialize the matrices M,N,P

// I/O to read the input matrices M and N

//int size=Width*Width*sizeof(float);

float *M,*N,*P;

int Width=4;

//int size=Width*Width*sizeof(float);

int i=0;

M=(float *)malloc(sizeof(float)*Width*Width);

N=(float *)malloc(sizeof(float)*Width*Width);

P=(float *)malloc(sizeof(float)*Width*Width);

for(i=0;i<Width*Width;i++)

M[i]=(float)i;

for(i=0;i<Width*Width;i++)

N[i]=(float)i;

//      for(i=0;i<Width*Width;i++)

//              printf("%3f  ",N[i]);

// M*N on the device

MatrixMulOnDevice(M,N,P,Width);

for(i=0;i<Width*Width;i++)

{

if(i%Width==0)printf("\n");

printf("%3f   ",P[i]);

}

printf("\n");

// I/O to write the output matrix P

// Free matrices M, N, P

free(M);free(N);free(P);

return 0;

}

运行命令:

nvcc -deviceemu matrixmul.cu -o matrixmul

注意: -deviceemu在此处是必须的,因为在device中调用了printf,这属于device调用了host function

下一步:理解计算是怎样并行的?

普通CPU程序和GPU程序的性能比怎样?用时间衡量

CUDA学习笔记(一)——CUDA编程模型的更多相关文章

  1. CUDA学习笔记-1: CUDA编程概览

    1.GPU编程模型及基本步骤 cuda程序的基本步骤如下: 在cpu中初始化数据 将输入transfer到GPU中 利用分配好的grid和block启动kernel函数 将计算结果transfer到C ...

  2. 大数据学习笔记3 - 并行编程模型MapReduce

    分布式并行编程用于解决大规模数据的高效处理问题.分布式程序运行在大规模计算机集群上,集群中计算机并行执行大规模数据处理任务,从而获得海量计算能力. MapReduce是一种并行编程模型,用于大规模数据 ...

  3. 孙鑫VC学习笔记:多线程编程

    孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified ...

  4. Hadoop学习笔记(7) ——高级编程

    Hadoop学习笔记(7) ——高级编程 从前面的学习中,我们了解到了MapReduce整个过程需要经过以下几个步骤: 1.输入(input):将输入数据分成一个个split,并将split进一步拆成 ...

  5. WCF学习笔记之事务编程

    WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...

  6. Java并发编程的艺术读书笔记(2)-并发编程模型

    title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...

  7. ArcGIS案例学习笔记-批量裁剪地理模型

    ArcGIS案例学习笔记-批量裁剪地理模型 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 功能:空间数据的批量裁剪 优点:1.批量裁剪:任意多个目标数据,去裁剪任意 ...

  8. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  9. Java学习笔记之---单例模型

    Java学习笔记之---单例模型 单例模型分为:饿汉式,懒汉式 (一)要点 1.某个类只能有一个实例 2.必须自行创建实例 3.必须自行向整个系统提供这个实例 (二)实现 1.只提供私有的构造方法 2 ...

  10. WebGL three.js学习笔记 加载外部模型以及Tween.js动画

    WebGL three.js学习笔记 加载外部模型以及Tween.js动画 本文的程序实现了加载外部stl格式的模型,以及学习了如何把加载的模型变为一个粒子系统,并使用Tween.js对该粒子系统进行 ...

随机推荐

  1. android经典实战项目视频教程下载

    注:这是一篇转载的文章,原文具体链接地址找不到了,将原文分享如下,希望能对看到的朋友有所帮助! 最近在学习android应用方面的技术,自己在网上搜集了一些实战项目的资料,感觉挺好的,发布出来跟大伙分 ...

  2. Win7 + ubuntu14.04 双系统

    安装主要分为以下几步:一. 下载Ubuntu 14.04镜像软件:二. 制作U盘启动盘:三. 安装Ubuntu系统:四. 用EasyBCD 创建启动系统. 1. 下载 Ubuntu 14.04 直接到 ...

  3. jquery------提供灵活的方法参数

    index.jsp <h1 >再次重逢的世界</h1> my.js $(document).ready(function(){ (function($){ $.fn.shado ...

  4. 使用存取方法来设置Property value

    对比如下代码,第一种使用了存取方法来设置,第二种直接对实例变量操作.显然我们应该采用第一种, 使用第二种情况,简单的情况还好,如果情况一旦复杂,就非常容易出错.并且直接对实例变量操作,不会引发KVO通 ...

  5. dll劫持技术

    DLL劫持技术当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址空间中,加载器分析可执行模块的输入表,并设法找出任何需要的DLL,并将它们映射到进程的地址空间中. DLL劫持原理 ...

  6. Run UliPad 4.1 Under Windows 7 64bit and wxPython 3.0.2

    Abstract: UliPad that is developed by limodou is an excellent code editor. It works well with wxPyth ...

  7. HDOJ 2389 Rain on your Parade

     HK.... Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K ...

  8. 微信用户量破6.5亿 首超移动QQ

    腾讯控股有限公司昨日公布了微信和WeChat合并月活跃用户量达到6.5亿,同比再涨39%.QQ在移动智能终端月活为6.39亿,同比增长18%,尽管势头也不错,但这是第一次,微信干掉了移动QQ! 201 ...

  9. 没玩过这些微信小游戏你就out了

    你确定没玩过下面这些微信小游戏?是不是有点out了?赶紧添加微信号kangfuyk,回复H5马上畅玩! 当然了,扫一下二维码关注后回复H5更快捷噢! 微信小游戏列表,持续更新中 辨色大比拼!心理游戏 ...

  10. 织梦系统规律:查看网站是不是用dedecms建的

    用dedecms织梦系统建站的童鞋,在遇见很喜欢的网站的时候总想知道人家的网站是用什么做的,怎么知道网站是不是dedecms建的呢?? 第一个方法: 可以直接在需要判断网站织梦版本的的URL路径后面添 ...