Heterogeneous Parallel Programming(异构并行编程)学习笔记(一)

原创 2012年12月13日 22:29:58

好记性不如烂笔记。以下是在Coursera学习Heterogeneous Parallel Programming时记录的一些要点。


Wiki对Heterogeneous Programming的解释如下:

Heterogeneous computing systems refer to electronic systems that use a variety of different types of computational units. A computational unit could be a general-purpose processor (GPP), a special-purpose processor (i.e. digital signal processor (DSP) or graphics processing unit (GPU)), a co-processor, or custom acceleration logic (application-specific integrated circuit (ASIC) or field-programmable gate array (FPGA)). 

简要的说,就是采用不同类型的计算节点协同进行计算。而Heterogeneous Parallel Programming则是建立在这种机制上的并行计算。这里使用的是的CUDA。CUDA是NVIDIA推出的建立在C语言和GPU基础上的计算框架。详细情况可参考《NVidia CUDA C Programming Guide》。


1. GPU与CPU

GPU与CPU的设计理念不同:GPU旨在提供高吞吐量,而CPU旨在提供低延迟的操作,如下图所示:


CPU需要降低指令的执行时间,所以有很大的缓存,而GPU则不然。单一的GPU线程执行时间相当长,因此总是多线程并行,这样提高了吞吐量。

综上,在串行计算部分应该使用CPU,而并行计算部分则应使用GPU。


2. CUDA计算模型

CUDA中计算分为两部分,串行部分在Host上执行,即CPU,而并行部分在Device上执行,即GPU。

相比传统的C语言,CUDA增加了一些扩展,包括了库和关键字。CUDA代码提交给NVCC编译器,该编译器将代码分为Host代码和Device代码两部分。Host代码即为原本的C语言,交由GCC或其他的编译器处理;Device代码部分交给一个称为实时(Just in time)编译器的组件,在给代码运行之前编译。


3. Device上的并行线程阵列

并行线程阵列由Grid——Block——Thread三级结构组成,如下图所示:


每一个Grid中包含N个Block,每一个Block中包含N个Thread。

这里需要提到SPMD概念:SPMD,即Single Program Multiple Data,指相同的程序处理不同的数据。在Device端执行的线程即属于此类型,每个Grid中的所有线程执行相同的程序(共享PC和IR指针)。但是这些线程需要从共享的存储中取得自身的数据,这样就需要一种数据定位机制。CUDA的定位公式如下:

i = blockIdx.x * blockDim.x + threadIdx.x

bllockIdx标识Block,blockDim为Block在该维度上的大小,threadIdx为在Block内部线程的标识。

注意到后缀的.x,这是因为CUDA的线程阵列可以是多维的(如上图),blockIdx和threadIdx最多可以达到3维。这能够为处理图像和空间数据提供极大的便利。


4. Device上的内存模型

Device上的内存模型如下图所示:


每个Grid有一个共享的存储,其中每个线程有自己的寄存器。Host代码负责分配Grid中的共享内存空间,以及数据在Host、Device之间的传输。Device代码则只与共享内存、本地寄存器交互。


5. CUDA基本函数

与C语言中的函数想对应,CUDA有以下几个基本函数:

cudaMalloc()、cudaFree()、cudaMemcpy()

其作用等同于C中的对应函数,不同之处在于这些函数操作的是Device中的共享内存,cudaMemcpy()则用于Host内存与Device内存传输数据。


6. 函数标识

CUDA的函数分为三种:


注意都是双下划线。其中的__global__函数即为C代码中调用Device上计算的入口。

__host__函数为传统的C函数,也是默认的函数类型。之所以增加这一标识的原因是有时候可能__device__和__host__共同使用,这时可以让编译器知道,需要编译两个版本的函数。


7. 例:向量加法

注意:这不是一个完整的程序,只用于体现主要步骤

#include<cuda.h>

...

// vector addition

void vecAdd(float *h_A, float *h_B, float *h_C, int n)

{

int size = n * sizeof(float);

float *d_A;

float *d_B;

float *d_C;


// allocate device memory for A, B, C

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

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

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


// transfer data from host to device

cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);

cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);


// specify the dimension for Grid and Block first

// 256 threads in one block, and make sure there are enough grid to cover all the vector

dim3 gridDim((n-1) / 256, 1, 1);

dim3 blockDim(256, 1, 1);


// kernel invocation code

vecAddKernel<<<gridDim, blockDim>>>(d_A, d_B, d_C, n);


// transfer result from device to host

cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);

// free memory

cudaFree(d_A);

cudaFree(d_B);

cudaFree(d_C);

}


// vector addition kernel function with __global__ identifier

__global__

void vecAddKernel(float *d_A, float *d_B, float *d_C, int n)

{

// calculate index

int i = blockIdx.x * blockDim.x + threadIdx.x;

if (i < n)

d_C[i] = d_A[i] + d_B[i];

}


Heterogeneous Parallel Programming(异构并行编程)学习笔记(五)

这里主要讲述两种并行计算模式,前缀求和(Prefix Sum)以及卷积(Convolution)。 1. Prefix Sum 前缀求和由一个二元操作符和一个输入向量组成,虽然名字叫求和,...
  • huhumama0
  • huhumama0
  • 2013年01月09日 17:14
  • 2179

Heterogeneous Parallel Programming(异构并行编程)学习笔记(七)

这里主要介绍MPI框架,以及怎样将其与CUDA结合起来运用。 1. MPI MPI可以视为大一号的CUDA。一个MPI框架由分布式计算节点组成,每一个节点可以视为是一个“Thread”,但...
  • huhumama0
  • huhumama0
  • 2013年01月22日 16:36
  • 2163

Heterogeneous Parallel Programming(异构并行编程)学习笔记(六)

这里主要介绍CUDA的Overlapping计算。 1. Pinned Memory 所谓的Pinned Memory,是一种锁定内存物理地址的方法,对应于操作系统的分页技术。众所周知,操...
  • huhumama0
  • huhumama0
  • 2013年01月22日 14:18
  • 2331

Heterogeneous Parallel Programming(异构并行编程)学习笔记(三)

米国人都去过圣诞了,这次内容不多。 1. Bursting 由于种种原因,DRAM的核心速度低于接口速度,因此引入了所谓Bursting的技术。Bursting,是指当读取DRAM时,返回...
  • huhumama0
  • huhumama0
  • 2012年12月23日 19:26
  • 2414

Heterogeneous Parallel Programming(异构并行编程)学习笔记(四)

这次的内容主要集中在Reduction模型上。 1. Reduction Reduction是一种广泛使用的计算模型,特别是在并行计算领域。简单地来说,Reduction就是一系列的划分(...
  • huhumama0
  • huhumama0
  • 2013年01月07日 15:43
  • 2083

Heterogeneous Parallel Programming(异构并行编程)学习笔记(二)

这里讲讲二维数据和内存模型 1. 二维参数设置 前面已经说过,CUDA支持多维的Grid和Block,以方便处理多维数据,那么在调用Kernel时函数也会有所不同。假定需要处理一张76x6...
  • huhumama0
  • huhumama0
  • 2012年12月16日 21:50
  • 2477

[大规模并行处理器编程实战]读书笔记_Heterogeneous Parallel Programming_CHAPTER_03

前两课都是铺垫,终于来到正题。 先说的数据并行性,这个概念对所有并行计算开发都是非常有用的。 应用程序可以使用两种(或者其中一种)基本形式,在这里被称作“数据并行”和“处理并行”。数据并行指同...
  • Orion1982
  • Orion1982
  • 2015年01月14日 08:26
  • 384

[大规模并行处理器编程实战]读书笔记_Heterogeneous Parallel Programming_CHAPTER_02

GPU 计算的发展历程 固定功能的图形流水线 (GeForce 3 时代 , ATI 9700) 最初的GPU只是用于游戏和视频,所以在设计上并没有为开发人员预留并行计算的API。...
  • Orion1982
  • Orion1982
  • 2015年01月13日 10:21
  • 315

Java并行编程(parallel programming)

多核处理器已经在计算机上的广泛应用,为了更好的利用多处理器的长处,软件需要运行在并行状态下。JDK7引入了全新的Fork/Join架构用于并行编程,这可以应用于多处理器的机器上以提高程序的效率。 F...
  • baidu_17313961
  • baidu_17313961
  • 2015年12月17日 13:45
  • 1093

Java并行编程(parallel programming) 2

另一个并行编程的例子是利用并行编程方法寻找一个大数组中的最大值,为了得到最大值我们需要得到一个最大值的返回值,因此我们定义了一个继承自RecursiveTask任务类,compute需要重写来返回数组...
  • baidu_17313961
  • baidu_17313961
  • 2015年12月18日 09:30
  • 424
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Heterogeneous Parallel Programming(异构并行编程)学习笔记(一)
举报原因:
原因补充:

(最多只允许输入30个字)