CUDA学习笔记(一)——CUDA编程模型
转自: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编程模型的更多相关文章
- CUDA学习笔记-1: CUDA编程概览
1.GPU编程模型及基本步骤 cuda程序的基本步骤如下: 在cpu中初始化数据 将输入transfer到GPU中 利用分配好的grid和block启动kernel函数 将计算结果transfer到C ...
- 大数据学习笔记3 - 并行编程模型MapReduce
分布式并行编程用于解决大规模数据的高效处理问题.分布式程序运行在大规模计算机集群上,集群中计算机并行执行大规模数据处理任务,从而获得海量计算能力. MapReduce是一种并行编程模型,用于大规模数据 ...
- 孙鑫VC学习笔记:多线程编程
孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010 HQU Email:zgzhaobo@gmail.com QQ:452728574 Latest Modified ...
- Hadoop学习笔记(7) ——高级编程
Hadoop学习笔记(7) ——高级编程 从前面的学习中,我们了解到了MapReduce整个过程需要经过以下几个步骤: 1.输入(input):将输入数据分成一个个split,并将split进一步拆成 ...
- WCF学习笔记之事务编程
WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...
- Java并发编程的艺术读书笔记(2)-并发编程模型
title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...
- ArcGIS案例学习笔记-批量裁剪地理模型
ArcGIS案例学习笔记-批量裁剪地理模型 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 功能:空间数据的批量裁剪 优点:1.批量裁剪:任意多个目标数据,去裁剪任意 ...
- java学习笔记15--多线程编程基础2
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...
- Java学习笔记之---单例模型
Java学习笔记之---单例模型 单例模型分为:饿汉式,懒汉式 (一)要点 1.某个类只能有一个实例 2.必须自行创建实例 3.必须自行向整个系统提供这个实例 (二)实现 1.只提供私有的构造方法 2 ...
- WebGL three.js学习笔记 加载外部模型以及Tween.js动画
WebGL three.js学习笔记 加载外部模型以及Tween.js动画 本文的程序实现了加载外部stl格式的模型,以及学习了如何把加载的模型变为一个粒子系统,并使用Tween.js对该粒子系统进行 ...
随机推荐
- Notions of Flow Networks and Flows
这篇随笔是对算法导论(Introduction to Algorithms, 3rd. Ed.)第26章 Maximum Flow的摘录. ------------------------------ ...
- UVA116Unidirectional TSP(DP+逆推)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18206 题意:M*N的数阵,从左边一列到右边一列走过的数的和的最小.并输出路 ...
- Java Web文件上传
参考资料:http://www.cnblogs.com/xdp-gacl/p/4200090.html 一.问题描述 Java Web文件上传需要借助一些第三方库,常用的是借助Apache的包,有两个 ...
- 七层负载均衡——HAProxy
HAProxy入门 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,HAProxy是完全免费的.借助HAProxy可以快速并且可靠的提供基于TCP ...
- [转载]给Jquery动态添加的元素添加事件
原文地址:给Jquery动态添加的元素添加事件作者:小飞侠 我想很多人都会向我一样曾经 被新元素的事件绑定困惑很久也就是在页面加载完成后给元素绑定了事件,但又新增加的元素上却没有绑定任何事件. js的 ...
- php + mysql 分布式事务(转)
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元: 事务应该具有4个属性:原子性.一致性.隔离性.持续性 原子性(atomicity).一个事务是一个不可分割的工作单 ...
- 基于TcpListener的web服务器
写在前面 上篇文章根据<asp.net 本质论>书上提供的例子,实现了一个简单的web服务器,本篇文章将介绍另一种实现方式——基于TcpListener的web服务器. TcpListen ...
- XSS跨站脚本攻击实例讲解,新浪微博XSS漏洞过程分析
2011年6月28日晚,新浪微博遭遇到XSS蠕虫攻击侵袭,在不到一个小时的时间,超过3万微博用户受到该XSS蠕虫的攻击.此事件给严重依赖社交网络的网友们敲响了警钟.在此之前,国内多家著名的SNS网站和 ...
- Model backing a DB Context has changed; Consider Code First Migrations
Model增加一个字段,数据库对应的也手动添加了字段但是运行时报错 The model backing the 'TopLogDbContext' context has changed since ...
- 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻
连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...