并行计算:GPU与CPU比较以及并行计算初步学习

Posted 说到做到_我的忍道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并行计算:GPU与CPU比较以及并行计算初步学习相关的知识,希望对你有一定的参考价值。

一、GPU与CPU结构上的对比

Multicore machines and hyper-threading technology have enabled scientists, engineers, and financial analysts to speed up computationally intensive applications in a variety of disciplines. Today, another type of hardware promises even higher computational performance: the graphics processing unit (GPU).

Originally used to accelerate graphics rendering, GPUs are increasingly applied to scientific calculations. Unlike a traditional CPU, which includes no more than a handful of cores, a GPU has a massively parallel array of integer and floating-point processors, as well as dedicated, high-speed memory. A typical GPU comprises hundreds of these smaller processors (Figure 1).

从上图可以看出:CPU的核心数是远远小于GPU的核心数的,虽然CPU每个核心的性能非常强大,但是典型的GPU都包含了数百个小型处理器,这些处理器是并行工作的,如果在处理大量的数据时,就会表现出相当高的效率,这就是所谓的众人拾柴火焰高。

二、GPU加速个人应用程序

这两个条件的第二个我觉得是进行GPU计算的大前提,正是因为任务能够碎片化,才能够充分利用GPU的物理结构,从而提高计算效率。第一个说则条件说明了GPU计算需要将数据传输给GPU显存,这一步会花一些时间,如果数据传输花费的时间比较多的话,那就不推荐使用GPU计算啦。

三、并行计算

并行计算(Parallel Computing)是指同时使用多种计算资源解决计算问题的过程,是提高计算机系统计算速度和处理能力的一种有效手段。它的基本思想是用多个处理器来协同求解同一问题,即将被求解的问题分解成若干个部分,各部分均由一个独立的处理机来并行计算。并行计算系统既可以是专门设计的、含有多个处理器的超级计算机,也可以是以某种方式互连的若干台的独立计算机构成的集群。通过并行计算集群完成数据的处理,再将处理的结果返回给用户。

平台是并行计算的载体,它决定着你可以用或只能用什么样的技术来实现并行计算。

多核和集群技术的发展,使得并行程序的设计成为提高数值计算效率的主流技术之一。常用的小型计算平台大致分为:由多核和多处理器构建的单计算机平台;由多个计算机组成的集群(Cluster)。前者通过共享内存进行数据交互,后者通过网络进行数据通信。

计算正在从 CPU(中央处理)向 CPU 与 GPU(协同处理)的方向发展。

GPU最早主要应用在图形计算机领域,近年来,它在通用计算机领域得到了迅猛的发展,使用GPU做并行计算已经变得越来越重要和高效。

常用的并行计算技术包括多线程技术、基于共享内存的OpenMP技术,基于集群的MPI技术等。但它们都需要用户处理大量与并行计算算法无关的技术细节,且不提供高效的算法库,与数值计算的关联较为松散。

四、Matlab与并行计算

1. 并行池

1.1 开启和配置并行池

在使用parfor和spmd之前,首先要配置和开启并行计算池。parpool函数提供并行池的配置和开启功能,其用法如下

在matlab中输入 p=parpool, 输出结果如下图

 

输出参数p为并行池对象,一个池对象有7种属性。其中,“NumWorkers” 代表worker的个数,也就是说开启了4个并行池;“IdleTimeout”指定了池定时关闭的时长,单位为分钟,图中为30分钟;“SpmdEnabled”指定池是否可以运行SPMD代码,其它属性相见Matlab 并行工具箱手册
此外,可以通过p.Property 访问和设置属性,如p.IdleTimeout = 10; 可以设置定时关闭池的时长为10分钟。

1.2 获取当前池

如果在启动池时没有设置输出参数p,可以使用gcp函数获取当前池的对象,gcp的用法如下表

Matlab中,使用delete函数关闭或删除池,用法:delete(poolobj),其中poolobj为要关闭的池对象。

2. 循环并行parfor

2.1 matlab client和matlab worker

Matlab并行执行parfor循环时,采用client和worker模式。其中client指编写和启动并行代码的Matlab端,worker指并行运行代码的Matlab端。用户可以将Matlab软件理解为一个进程,在同一计算机或网络上的多个计算机上可以运行多个Matlab进程,每个Matlab进程之间通过某种方式进行数据传输,用户首先在client端编写代码,然后再client端运行编写的代码,在运行代码的过程中,如果某个程序需要并行执行,Matlabclient端根据并行代码的关键字及类型将并行代码分配到本机或网络上的其它Matlab进程执行,那些最终执行并行代码的Matlab进程即为worker。右图显示了,Matlab client 对parfor关键字的处理,它将任务分配到多个Matlab workers 上并行执行程序。假设m为Matlab worker的数量,循环次数为n,若n/m为整数的话,则循环将被均匀划分到Matlab worker;否则,循环被非均匀划分,有些Matlab worker的负载会大些。

2.2 并行程序的parfor循环 

应用parfor的一个基本前提是循环可以被等效分解,即分解后的循环的执行顺序不会影响最终结果。parfor的用法与for类似,其语法如下

并行计算间的数据转移大小极限受Java虚拟机(JVM)内存分配的限制。在MJS集群上执行job的client和worker间的单次数据转移量也受此限制。具体大小限制取决于系统结构。

每次转移数据的最大量与系统结构的关系

2.3 利用parfor并行for循环的步骤

使用parfor并行for循环的基本步骤为:

1)       使用parpool函数配置和开启并行计算池。

2)       将串行循环中的for关键字改为parfor,并注意是否要修改循环体,以满足特定要求,如循环变量的类型要求(参见参考手册)

3)       执行完毕后若不再进行并行计算,使用delete关闭并行池。

3. 批处理

3.1 运行批处理任务

创建mywave.m脚本文件,输入如下代码并保存:

for i=1:1024

  A(i) = sin(i*2*pi/1024);

end

在命令行窗口输入:job = batch('mywave'),Matlab以下图所示方式并行运行:

然后等待作业完成:wait(job),使用load命令将数据从Matlabworker 转移到Matlabclient的workspace,即load(job,’A’)。任务完成后,使用delete(job)永久删除它的数据。

3.2 运行批处理并行循环

打开mywave.m脚本文件,修改for为parfor,保存,代码如下:

parfor i=1:1024

  A(i) = sin(i*2*pi/1024);

end

 输入:job =batch('mywave','Pool',2),以两个worker来执行parfor并行循环任务,所以此例总共使用3个本地worker,如下图

同样的,依次使用wait(job)load(job,'A'),将数据从worker的workspace转移到client的workspace。最后,使用delet(job)删除数据。

4. matlab的GPU计算

Matlab 的GPU计算实现MATLABworkspace和图形处理器(GPU)间的数据传递;在GPU上执行代码。

用户可以使用计算机的GPU处理矩阵运算,在大多数情况下,在GPU上执行要比在CPU上快。

Matlab的GPU计算提供了下表 2‑5所列的14种MATLAB函数和1种C语言函数,表中仅简要介绍函数功能,具体参见Matlab并行工具箱参考手册。

GPU计算函数列表

Matlab GPU计算提供的类

关于各类的具体含义和各函数的详细用法请参见MATLAB并行工具箱手册。

下面主要从:GPU设备查询、在GPU上创建数组、在GPU上运行内置函数、在GPU上运行自定义函数四个方面说明Matlab GPU计算支持的技术,此外,用户还可以在GPU上运行CUDA或PTX代码、运行包含CUDA代码的MEX-函数等等,详见MATLAB并行工具箱手册和文献[3]的第10章。

4.1 GPU 设备查询与选择

GPU设备查询与选择

在使用GPU设备之前,可以利用gpuDeviceCount函数查看计算机当前可用GPU设备数量,若存在可用的GPU设备,则输出大于等于1的数。

在Matlab中使用gpuDevice(IDX)来选择第IDX个GPU设备,起始编号为1,如输入gpuDevice(1),输出右图所示结果:

其中,“MaxThreadsPerBlock”表示每个Block的最大线程数;“MaxShmemPerBlock”表示每个Block可用的最大共享内存大小;“TotalMemory”表示GPU拥有的所有内存,图中为4.2950e+09Byte,即4GB;“AvailableMemory”代表可用内存;“MultiprocessorCount”表示GPU设备处理器个数;“DeviceSupported”表示本机Matlab支持的GPU设备数。

4.2 在GPU上创建阵列

有两种方式在GPU上创建阵列:从Workspace转移和直接创建。

1)       从Workspace转移到GPU

使用gpuArray函数来把数据从Workspace转移到GPU,如下面的代码所示,将Workspace中的阵列A转移到GPU中,并存为G,原Workspace中的A阵列并不消失。

A = [1 2 3;4 5 6];

G = gpuArray(A);

该函数支持对非稀疏阵列且可以是:'single','double','int8','int16','int32','int64','uint8','uint16','uint32','uint64',or 'logical'类型。

2)    直接创建GPU阵列

gpuArray类提供了一些方法来在GPU上直接创建阵列,这样就不需要从Workspace进行转移。可用的有:

gpuArray类提供的创建GPU阵列的方法

如:G = ones(100,100,50,'gpuArray');在GPU上创建一个100-by-100-by-50的阵列。

此外,支持gpuArray阵列的方法还有abs,cos,fft,conv,plot等等共369个方法。若要查看,输入如下命令即可查看:

如果,要查看某个方法的帮助,输入如下命令查看:

help gpuArray/functionname

其中,functionname为函数名,如:help gpuArray/dot

3)       从GPU上回收数据

从GPU上回收数据,即把数据从GPU转移到MatlabWorkspace。在Matlab中使用gather函数来取回GPU上的数据并存在Matlab的 Workspace中。可以使用isequal函数来验证转移前后,值是否相同。如下代码将GPU中的阵列G传回到Workspace生成D。

G = gpuArray(ones(100,'uint32'));

D = gather(G);

OK = isequal(D,G)

4.3 在GPU上运行内置函数

代码主要实现对GPU上的阵列Ga进行FFT变换,并将结果回收到Workspace。可见内置函数的调用与普通串行程序没有大的区别,只是输入阵列的类型为gpuArray。

4.4 在GPU上运行自定义函数

Matlab中使用arrayfunbsxfun来执行自定义的函数,即

result = arrayfun(@myFunction,arg1,arg2);

下面举例来说明,创建myfun.m文件,打开输入如下代码:

function [ absga1,absga2,maxga ] = myfun( ga1,ga2 )

absga1 = abs(ga1);

absga2 = abs(ga2);

maxga = max(absga1,absga2);

该代码实现对输入阵列ga1,ga2的每个元素取绝对值,然后取出两者中对应最大的。为了运行并查看结果,创建一个脚本,输入如下代码:

ga1 = [-1 5 -3]

ga2 = gpuArray([4 -6 -2])

[absga1,absga2,maxga] = arrayfun(@myfun,ga1,ga2)

absda1 = gather(absga1)

absda2 = gather(absga2)

maxda = gather(maxga)

通过上述程序,可以看出,在自定义函数myfun中,只要有一个输入参数的类型为gpuArray,则整个函数myfun都将运行在GPU中,对于非gpuArray类型的阵列,Matlab自动进行转换。

除了可以调用Matlab自身支持的函数外,可以自己编写支持GPU的Matlab函数。自定义的函数中可以调用的函数和操作如下表 2 8:

自定义函数中支持gpuArray的函数和操作

 

 

以上是关于并行计算:GPU与CPU比较以及并行计算初步学习的主要内容,如果未能解决你的问题,请参考以下文章

GPU是并行计算,CPU是串行计算?为啥这么说?

GPU是并行计算,CPU是串行计算?为啥这么说?

深度学习并行运算原理 以及 keras实现GPU并行

您好有个问题请教一下cpu怎么和gpu并行计算处理好日常软件

从零开始学习OpenCL开发架构

CUDA编程入门极简教程(转)