portmaintain application code. OpenMP and OpenACC are two popular models used to port applications to accelerators. However, neither of the models provides support for multiple GPUs. A plausible solution is to use combination of OpenMP and OpenACC that forms a hybrid model; however, building this model has its own limitations due to lack of necessary compilers’ support. Moreover, the model also lacks support for direct device-to-device communication. To overcome these limitations, an alternate strategy is to extend OpenACC by proposing and developing extensions that follow a task-based implementation for supporting multiple GPUs. We critically analyze the applicability of the hybrid model approach and evaluate the proposed strategy using several case studies and demonstrate their effectiveness."> Multi-GPU支持在单个节点上使用Directive-Based编程模型 - raybet雷竞app,雷竞技官网下载,雷电竞下载苹果

科学的规划

PDF
科学的规划/2015年/文章
特殊的问题

编程模型、语言和编译器的冲击和异构体系结构

把这个特殊的问题

研究文章|开放获取

体积 2015年 |文章的ID 621730年 | https://doi.org/10.1155/2015/621730

芭芭拉Rengan Xu Xiaonan田,萨尼塔•钱德拉塞卡兰查普曼, Multi-GPU支持在单个节点上使用Directive-Based编程模型”,科学的规划, 卷。2015年, 文章的ID621730年, 15 页面, 2015年 https://doi.org/10.1155/2015/621730

Multi-GPU支持在单个节点上使用Directive-Based编程模型

学术编辑器:新民田
收到了 2014年5月15
接受 2014年9月29日
发表 2015年10月01

文摘

现有的研究表明,使用单一的GPU可以获得显著的性能提升。我们应该能够实现进一步的性能加速如果我们使用一个以上的GPU。异构处理器组成的多个cpu和gpu提供了巨大的潜力,通常被视为一个主要候选人移植复杂的科学应用。不幸的是编程异构系统需要更多的努力比传统的多核系统所必需的。Directive-based编程方法被广泛采用,因为他们使它易于使用 港口 保持应用程序代码。OpenMP和OpenACC是两种受欢迎的模型用于港口应用程序加速器。然而,无论是模型提供了对多个gpu的支持。一个合理的解决方案是使用组合的OpenMP OpenACC组成一个混合模型;然而,建造这个模型有其自身的限制由于缺乏必要的编译器的支持。此外,该模型还缺乏对直接设备间通信的支持。为了克服这些限制,另一个策略是延长OpenACC提出和发展中扩展,支持多个gpu的基于任务的实现。我们批判性分析的适用性提出的混合模型方法和评估策略使用几个案例研究和证明其有效性。

1。介绍

异构体系结构在过去的几年中获得了大受欢迎。这些异构体系结构通常由连接到主机cpu的加速器,和这样的加速器可能包括gpu, dsp、FPGA。虽然异构体系结构有助于显著提高计算能力,他们也带来了潜在的挑战前程序员这些新架构的功能可以利用。CUDA (1]和OpenCL [2gpu)提供两个不同的接口程序。但为了执行有效的使用这些接口编程,程序员需要彻底理解底层架构和语言/模型。这会影响生产力。为了克服这些困难,许多高层directive-based编程模型已经提出,包括HMPP [3],PGI [4],OpenACC [5]。这些模型只允许程序员将指令和运行时调用插入到应用程序代码,使部分或全部Fortran和C / c++代码便携式加速器。OpenACC是一个新兴的界面平行程序员方便地创建和编写简单加速器上执行的代码。2013年8月,OpenACC标准委员会公布的第二个版本的API, OpenACC 2.0。供应商公司,克雷和PGI OpenACC 2.0提供的编译器支持。帽,之前跑业务,还提供支持OpenACC 2.0。该模型的目标是将科学应用移植到一个以上的GPU。几家大型应用地球物理学领域的,天气预报需要大规模并行计算和这样的应用程序可以很容易地从多个gpu中获益。我们如何创建合适的软件,可以利用多个gpu不失性能的可移植性?这仍然是一个挑战。 In a large cluster, multiple GPUs could reside within a single node or across multiple nodes. If multiple GPUs are used across nodes and each node has one GPU, then the CPU memory associated with the corresponding GPU is independent of the CPU memory associated with another GPU. This makes the communication between the GPUs easier since the CPU memories associated with those GPUs are distributed. However, multiple GPUs could also be in a single node. Since each node in a cluster is usually a shared memory system which has multiple processors, the same shared memory is associated with multiple GPUs. This makes the communication between these GPUs more difficult since they share the same CPU memory and thus the possible memory synchronization issue arises. This paper only focuses on multi-GPU within a single node.

在本文中,我们利用使用多个gpu开发策略。(我)探索编程使用directive-based multi-GPU编程方法的可行性。(2)评估性能通过使用OpenMP和OpenACC multi-GPU平台混合模型。(3)提出扩展OpenACC编程支持多个加速器在单个节点。我们分类实验分析分为三种类型:(一)端口完全独立的例程或内核multi-GPU, (b)将一个大的工作量分成几个独立subworkloads然后分发每个subworkload GPU。在这两种情况下,gpu之间没有沟通,(c)中使用工作负载的方式,需要不同的gpu来相互沟通。

本文的组织如下。部分2突出了这方面的相关工作;部分3概述了OpenMP和OpenACC directive-based编程模型。节4,我们将讨论我们的策略开发混合模型使用OpenMP OpenACC-based混合模型和港口三个科学应用在单节点multi-GPU使用NVIDIA GPU的卡片。节5我们建议新扩展OpenACC编程模型解决混合模型的限制。部分6提供我们工作的结论。

现有研究directive-based加速器关注地图应用程序编程方法只有单一的GPU。廖et al。6)提供加速器支持使用OpenMP 4.0编译器上升。田et al。7)和雷耶斯et al。8)开发的开源OpenACC编译器、OpenUH accULL,分别。他们的方法使用source-to-source技术翻译CUDA程序或OpenCL OpenACC程序。除了编译器的开发,也有广泛的研究(9- - - - - -11使用OpenACC)移植应用程序。然而,这些作品都只使用一个GPU,主要是因为OpenACC和OpenMP还不提供支持多种加速器。

单个编程模型可能不足以提供支持多种加速器设备;然而,用户可以应用混合模型来实现这一目标。哈特et al。12)使用Coarray Fortran (CAF)和OpenACC和几何et al。13)使用MPI和OpenACC程序中的多个GPU集群GPU。inter-GPU通信在这些作品是由分布式共享内存管理(DSM) MPI模型CAF或分布式内存模型。与这些作品不同的是,我们的工作使用OpenMP OpenACC混合模型。我们还开发一种方法,扩展了OpenACC模型来支持多个设备在一个集群节点。

目标多种设备的其他作品包括omps [14),允许用户在应用程序中使用他们自己的独特的指令,程序可以运行在多种gpu上共享内存系统或分布式内存系统。StarPU [15)是一种运行时库,安排任务到多个加速器。然而,这些方法的缺点是,omps和StarPU都需要用户手动编写内核被卸载的加速器。此外,他们的方法是没有任何标准的一部分,因此限制了可用性。

我们所知,只有其他编程模型支持多个加速器而不需要手动编写加速器内核文件HMPP [3),directive-based方法。然而,HMPP指令相当具有挑战性的可用性和将应用程序移植到加速器,甚至复杂的应用程序时不够大而复杂。

在本文中,我们采用了一个基于任务的概念提出了扩展OpenACC模型来支持多个加速器。这项工作是基于我们之前的工作16]。新的工作比我们之前的工作模型扩展的部分。相关工作,利用gpu的任务概念包括Chatterjee et al。17)设计了一个运行时系统,可以调度任务到不同的流多处理器(SMs)在一个设备。在他们的系统中,在一个特定时间,设备只能执行相同数量的线程块随着短信数量的开普勒20 c(13),从而限制性能。这是因为他们的系统是专为解决负载平衡问题在所有短信主要是为不规则的应用程序。扩展OpenACC Komoda等提出的模型。18)来支持多个gpu。他们提出了用户指定指令内存访问模式为每个数据计算区域和编译器识别工作负载分区。通常,很复杂,如果是用户识别所有数据的内存访问模式,特别是当数据多维或访问多个索引变量。在我们扩展OpenACC模型允许用户工作负载分区,从而进一步简化应用程序移植,使multi-GPU支持一般足以满足大多数应用情况。

3所示。概述OpenACC和OpenMP

OpenMP是一个高级directive-based为共享内存多核平台的编程模型。模型由一组指令,运行时库例程,环境变量。用户只需要简单地将指令插入现有的顺序代码,微小的改动或修改任何代码。OpenMP采用fork - join模型。模型以最初的主线程开始,然后一组线程将分叉的当程序遇到一个平行的构造,和所有其他线程将加入主线程结束时平行结构。在并行区域,每个线程都有自己的私有变量和工作的数据。不同线程之间的通信是由共享变量。在数据竞争条件的情况下,不同的线程将自动更新共享变量。从3.0开始,OpenMP介绍任务概念(19],可以有效地表达和解决不规则的并行性等问题的无限循环和递归算法。使任务实现高效,运行时需要考虑任务的创建、任务调度、任务切换、任务同步,等等。OpenMP 4.0在2013年发布包括支持加速器(20.]。

OpenACC [5),类似于OpenMP,是一个高级的编程模型,被广泛用于港口应用程序加速器。OpenACC还提供了一组指令,运行时例程,环境变量。OpenACC支持三级并行性:粗粒并行“帮派”,细粒度并行性和向量并行“工人,向量。“虽然OpenACC三个层次的并行映射到低水平CUDA编程模型,所有PGI帽(21],OpenUH [22每个帮派映射到一个线程阻塞,工人 线程阻塞和向量的维度 线程阻塞的维度。这保证公平性能比较时使用这些编译器,因为它们使用相同的并行性映射策略。执行模型假定主程序运行在主机上,而主程序的计算密集型地区都被附加的加速器。在内存模型中,通常的加速器和主机CPU由独立的内存地址空间;因此,来回传输数据处理是一个重要的挑战。以满足不同的数据优化的目的,OpenACC提供不同类型的数据传输条款1.0规范和可能的运行时例程2.0文档。要充分利用CPU资源,消除潜在的数据传输瓶颈,OpenACC还允许异步数据传输和异步计算CPU代码。还提供了一个模型更新指令可以使用数据区域内的主机和设备之间同步数据的记忆。

4所示。Multi-GPU支持与OpenMP和OpenACC混合模型

在本节中,我们将讨论策略探索编程multi-GPU使用OpenMP和OpenACC混合模型在一个节点。我们将评估策略使用三个科学应用。我们影响研究的方法通过比较和分析性能通过混合模型(multi-GPU实现)对单个的GPU实现。

实验平台是一个服务器机器,是一个多核系统组成的两个NVIDIA开普勒20 xm gpu。系统本身与24核Intel Xeon x86_64 CPU(12×2套接字),2.5 GHz的频率,和62 GB内存。每个GPU有5 GB全局内存。我们使用帽OpenACC S3D和PGI OpenACC矩阵乘法和2 d热方程。PGI编译器不用于S3D因为它不能成功编译代码。热方程2 d程序编制的帽子编译器非常长,所以我们在这里没有显示结果。帽编译器编译的矩阵乘法程序但我们离开性能比较与其他编译器后,在这里我们只验证混合编程模型的可行性。我们使用GCC 4.4.7帽主机所有C程序的编译器。对于一个Fortran程序,我们使用PGI和帽帽(pgfortran主机编译器)来编译OpenACC代码。我们使用最新版本的帽和PGI编译器,分别3.4.1和14.2。 CUDA 5.5 is used for our experiments. The CAPS compiler performs source-to-source translation of directives inserted code into CUDA code and then calls学校网站编译生成的CUDA代码。传递给帽编译器的旗帜是“-nvcc-options -Xptxas = - v,拱门,sm_35, -fmad = false,“和传递给PGI编译器的旗帜是“o3议员ta = nvidia cc35, nofma。“我们认为所评价的测量。我们都跑试验5次,然后平均性能结果。在即将到来的部分,我们将讨论单一和multi-GPU S3D热力学应用程序内核,实现矩阵乘法和2 d热方程。

OpenMP是相当容易使用,因为所有的程序员需要做的是插入OpenMP指令在适当的地方,如有必要,进行少量修改代码。OpenMP的大意和OpenACC混合模型,如图1是,我们需要手动把问题OpenMP线程,然后将每个线程关联到一个特定的GPU。最简单的情况是当每个GPU的工作是相互独立的,没有涉及到不同的GPU之间的沟通。但可能存在情况下,gpu将不得不相互通信,这将涉及到cpu。不同的gpu数据转移到相应的主机线程,这些线程通过共享变量,然后交流或交换数据和最后线程将新数据相关的gpu。GPU的直接技术(23),也可以不同的gpu之间直接传输数据而无需通过主机。这个没有可信的OpenMP OpenACC混合模型到目前为止,但在部分5我们将提出一些OpenACC编程模型的扩展,以适应这个特性。

4.1。S3D热力学内核

S3D [24)是一种流解算器执行的直接数值模拟湍流燃烧。S3D解决完全可压缩n - s、总能量、物种,和质量守恒方程加上详细的化学。除了控制方程,有额外的本构关系,比如理想气体状态方程,为化学反应速率模型,分子运输和热力学性质。这些关系和详细的化学性质已经被实现为内核或库适合GPU的计算。一些研究在[S3D已经完成13,25),但他们使用的代码是无法访问。对于我们工作的实验目的,我们只选择了两个不同的和独立的内核的大型S3D应用,详细讨论了在26]。

我们观察到的两个内核S3D有类似的代码结构和他们的输入数据是常见的。算法1显示了一个小单GPU实现的代码片段。内核,calc_mixcp和calc_mixenth包围一个主循环先生迭代。每个内核生成自己的输出结果,但结果是一样的,之前的迭代。两个内核可以在相同的执行顺序加速器在分享共同的输入数据,这将在GPU在整个执行时间。或者,他们也可以同时在不同的gpu执行,因为他们是完全独立的内核。

!美元acc数据copyout (c (1: np)、h (1: np)) copyin (T (1: np),…)
m = 1,先生
调用calc_mixcp (np, nslvs T midtemp,…,c)
调用calc_mixenth (np, nslvs T midtemp,…,h)
最后做
!美元acc端数据

为了使用multi-GPU,我们分配两个OpenMP线程的内核,并将每个线程与GPU。因为我们只有两个内核,没有必要使用omp对;相反,我们使用经济部分因此每个内核位于一个部分。每个线程都需要使用运行时设置设备号acc_set_device_num (int devicenum acc_device_t devicetype)。注意,设备数量从 OpenACC或运行时行为将实现定义的如果devicenum开始从 。为了避免设置设备数量在每一次迭代,使两个内核独立工作,我们应用循环裂变和原循环分割成两个循环。最后,我们复制的gpu通用数据。中的代码片段的算法2显示了multi-GPU实现。虽然是一个multi-GPU实现,每个内核的实现仍是一样一个GPU实现。图2显示了使用单一的GPU的性能结果和两个GPU。观察到两个GPU几乎总是采取大约一半的时间一个GPU。这说明了使用多个GPU的性能优势单一的GPU。

c所有omp_set_num_threads (2)
!美元omp平行私人(m)
!美元经济部分
!美元经济新闻节
调用acc_set_device_num (acc_device_not_host)
!美元acc数据copyout (c (1: np)) copyin (T (1: np),…)
m = 1,先生
调用calc_mixcp (np, nslvs T…,c)
最后做
!美元acc端数据
!美元经济新闻节
acc_device_not_host调用acc_set_device_num(2日)
!美元acc数据copyout (h (1: np)) copyin (T (1: np),…)
m = 1,先生
调用calc_mixenth (np, nslvs T…,h)
最后做
!美元acc端数据
!美元omp结束部分
!美元omp结束并行

4.2。矩阵乘法

S3D,我们有多个gpu分布不同内核的一个应用程序。另一种类型的案例研究将只有一个内核的工作负载分布到多个gpu,特别是如果工作量很大。我们将使用平方矩阵乘法探索这个案例研究作为一个例子。我们选择这个应用程序因为这个内核是广泛应用于众多的科学应用。这个内核并不构成复杂的简单动作,可以并行的数据分发不同的线程。我们还注意到一个大数据计算运动比率。

通常矩阵乘法需要矩阵和矩阵B作为输入,并生成矩阵C作为输出。当使用多个gpu,我们将使用相同数量的线程gpu在主机的数量。例如,如果系统有2个gpu,然后我们将推出2主机线程。一点然后我们分区矩阵块行操作这意味着每个线程将获得部分行矩阵A的每个线程都需要阅读整个矩阵B和产生的相应部分结果矩阵c .分区矩阵后,我们使用OpenACC执行每个分区段在一个GPU的计算。

算法3显示了一个代码片段multi-GPU实现矩阵乘法。在这里,我们假设可以均匀的线程数量除以平方矩阵行大小。由于外两个循环完全独立,我们分发 循环到所有帮派和 循环一个帮派的所有向量线程。我们只有2 gpu用于实验;然而,超过2 gpu,只要他们可以容易地使用可用的平台。在这个实现中,我们假设gpu可以均匀的数量除以线程的数量。我们为我们的实验使用不同的工作负载的大小。矩阵维度范围从1024年到8192年。图3(一个)显示了在使用一个和两个gpu性能比较。除了1024以外的数据大小,2 GPU的执行时间是几乎一半的只有1 GPU。为 作为矩阵的大小,我们几乎没有看到任何使用多个gpu中获益。这可能是由于开销由于托管线程的创建和GPU上下文设置。此外,两个gpu的计算不够大。当问题规模超过1024,multi-GPU实现显示性能大幅提高。在这些情况下,计算非常密集,上述费用被忽略。

omp_set_num_threads(线程);
# pragma omp平行
{
int i, j, k;
int id,块,开始,结束;
id = omp_get_thread_num ();
块= n /线程;
开始= id 块;
结束= (id + 1) 块;
acc_set_device_num (id + 1, acc_device_not_host);
# pragma acc数据copyin (A(开始 n: n])
copyin (B(0:n n])
copyout (C(开始 n: n])
{
# pragma acc并行num_gangs (32)vector_length (32)
{
# pragma acc循环帮派
(我=开始;我<结束;我+ +){
# pragma acc循环向量
(j = 0;j < n;j + +){
浮动c = 0.0 f;
(k = 0;k < n;k + +)
c + =( n + k] B(k n + j];
C( n + j]= c;
}
}
}

4.3。2 d热方程

我们注意到,在前面的两个情况下,内核在GPU是完全独立于内核的GPU。现在我们将探索情况有不同的gpu之间的沟通。这样一个有趣的应用是2 d热方程。热方程的公式来表示2 d(解释27),给出了如下: 在哪里 是温度, 是时间, 热扩散率, 在一个网格点。为了解决这个问题,一个可能的有限差分近似 在哪里 温度随时间变化的吗 , 在一个网格索引。在这个应用程序中,有一个网格边界点和内部点。边界点有一个初始温度和内点的温度也在更新。每个内部点更新其温度通过使用先前的相邻点的温度和本身。更新的操作温度为所有内部点在网格需要持续足够长的时间。这意味着需要多次迭代之前到达最终的稳定温度。在我们的程序中,迭代的数量是20000,我们的网格大小逐渐增加 。我们之前的工作经验在单一的GPU实现2 d热方程讨论了(11]。算法4显示了单一GPU实现的代码片段。内核更新内部温度,我们把外循环成所有帮派和内循环向量所有线程在每个帮派。因为最终的输出将被存储在temp1指针交换后,我们只需要传输这些数据主机。

void step_kernel{}
{
# pragma acc (temp_in平行的礼物(0: 新泽西],temp_out(0: 新泽西])
num_gangs (32)vector_length (32)
{
/ /遍历所有点域(边界除外)
# pragma acc循环帮派
(j = 1;j < nj-1;j + +){
# pragma acc循环向量
(i = 1;我< ni-1;我+ +){
/ /找到指数到线性内存
/ /为中心点和邻居
i00 = I2D (ni, i, j);
im10 = I2D (ni、张、j);
ip10 = I2D(倪,我+ 1,j);
i0m1 = I2D(倪,我,j - 1);
i0p1 = I2D (ni, i, j + 1);
/ /评估衍生品
d2tdx2 = temp_in(im10]2 temp_in(i00]+ temp_in(ip10];
d2tdy2 = temp_in(i0m1]2 temp_in(i00]+ temp_in(i0p1];
/ /更新温度
temp_out(i00]= temp_in(i00]+ tfac (d2tdx2 + d2tdy2);
}
}
}
}
# pragma acc (temp1数据副本(0: 新泽西])
copyin (temp2(0: 新泽西])
{
(istep = 0;istep < nstep;istep + +){
step_kernel(镍、新泽西、tfac temp1, temp2);
/ /交换临时指针
temp = temp1;
temp1 = temp2;
temp2 = temp;
}
}

让我们讨论的应用程序使用两个gpu。算法5显示了详细计划。在这个实现中,新泽西 网格的尺寸(不包括边界),分别。如图4,我们分区网格分成两部分 维度和一个GPU上运行每个部分。在计算之前,初始温度存储temp1_h更新后,温度,存储在新的温度temp2_h。然后我们交换指针,以便在下一次迭代的输入内核指向当前新的温度。自更新每个数据点都需要从上一次迭代周边点,两个gpu需要交换光环数据在每一个迭代。光环数据指的是需要交换的数据不同的gpu。到目前为止仅仅通过使用高级指令或运行时库,数据不能直接交换之间不同的gpu,唯一的解决方法是先将数据从一个设备从主机到主机,然后到另一个设备。在2 d热方程,不同的设备需要光环数据交换;因此,光环数据更新会通过CPU。因为不同的gpu使用网格中的数据的不同部分,我们不需要为这些部分分配单独的内存数据;相反,我们只需要使用私人指针指向共享变量的不同位置temp1_htemp2_h。让 代表一个线程的id;然后该线程指向的位置 网格的(因为它需要包含光环地区),和它需要转移 等于数据到设备行 。内核更新温度multi-GPU实现是一模一样的单一GPU实现。

omp_set_num_threads (NUM_THREADS);
行= nj / NUM_THREADS;
LDA =倪+ 2;
/ /主迭代循环
# pragma omp平行私人(istep)
{
浮动 temp1, temp2, temp_tmp;
int tid = omp_get_thread_num ();
acc_set_device_num (tid + 1, acc_device_not_host);
temp1 = temp1_h + tid LDA;
temp2 = temp2_h + tid LDA;
# pragma acc数据copyin (temp1(0:(行+ 2) 乔治。])
copyin (temp2(0:(行+ 2) 乔治。])
{
(istep = 0;istep < nstep;istep + +){
step_kernel (ni + 2, + 2行,tfac temp1, temp2);
/ 所有设备(除了最后一个)更新下晕到主机 /
如果(tid ! = NUM_THREADS-1){
# pragma acc更新主机(temp2( 乔治。:乔治。])
}
/ 所有设备(除了第一个)更新主机上光环 /
如果(tid ! = 0){
# pragma acc更新主机(temp2(乔治。:乔治。])
}
/ 所有主机线程在这里等,以确保晕所有设备的数据
已经更新到主机 /
# pragma omp障碍
/ 更新上晕所有设备(除了第一个) /
如果(tid ! = 0){
# pragma acc (temp2更新设备(0:乔治。])
}
/ 更新下晕所有设备(除了最后一个) /
如果(tid ! = NUM_THREADS-1){
# pragma acc (temp2更新设备((行+ 1) 乔治。:乔治。])
}
temp_tmp = temp1;
temp1 = temp2;
temp2 = temp_tmp;
}
/ 更新主机的最终结果 /
# pragma acc更新主机(temp1(乔治。: 乔治。])
}
}

3 (b)显示了不同实现的性能比较,也就是说,单身,multi-GPU实现。比较与单一multi-GPU GPU的性能时,我们注意到有一个微不足道的性能差异,当问题规模很小。然而,有一个显著增加性能使用multi-GPU较大的网格尺寸。网格大小 ,使用两个GPU加速的大约是2 x倍单一GPU实现。这是因为随着网格尺寸的增加,计算也显著增加,而光环数据交换仍然是足够小。因此,比率的计算/通信变得更大。可以使用multi-GPU有利于分解计算。

5。Multi-GPU OpenACC扩展的支持

我们看到,编程使用multi-GPU使用OpenMP和OpenACC混合模型显示了明显的性能优势4。然而,这种方法也有一些缺点。首先,用户需要学习两种不同的编程语言可能影响工作效率。第二,在这种方法中发生的设备间通信通过主机带来更多不必要的数据移动。第三,支持这样的混合模型对编译器是一个挑战。编译器提供了支持OpenMP和编译器为OpenACC B提供支持;结果,它不是简单的相互作用对不同的编译器。例如,克雷编译器不允许OpenACC指令出现在OpenMP指令(28];因此,算法中的示例35不是由克雷compilable编译器。尽管帽编译器支持OpenACC,它仍然使用一个OpenMP实现从另一个主机编译器,遵守和维护也是一个挑战。理想情况下,一个编程模型应该为multi-GPU提供支持。不幸的是,现有OpenACC标准还没有提供支持多种加速器编程。要解决这些问题,我们提出一些扩展OpenACC标准为了支持多个加速器设备。

5.1。提出指令扩展

我们的目标是帮助编译器和运行时实现设备主机将沟通,以便主机问题数据移动和内核启动请求发送到特定的设备。新的扩展描述如下:(1)# pragma acc /内核的deviceid平行(scalar-integer-expression):这是将相应的计算区域为特定的设备;(2)# pragma acc的deviceid数据(scalar-integer-expression):这是结构化数据的数据指令扩展;(3)# pragma acc的deviceid进入/退出数据(scalar-integer-expression);这是扩展非结构化数据;(4)# pragma acc等设备(scalar-integer-expression):这是用来同步所有活动在一个特定的设备由于默认情况下每个设备的执行异步使用多个设备时;(5)# pragma acc更新对等(列表)to_device(scalar-integer-expression)(列表)from_device(scalar-integer-expression);(6)无效acc_update_peer(无效 dst,int to_device,常量无效 src, int from_devicesize_t大小)的目的 是使设备间通信。当使用多个设备尤其重要,因为在一些加速器设备可以直接沟通与另一个设备不经过主机。如果设备不能直接沟通,运行时库可以选择首先传输数据到一个临时缓冲区在宿主体内,然后将它从主机转移到另一个设备。例如,在CUDA实现中,两台设备可以直接沟通只有当他们被连接到同一根I / O中心。如果不能满足这一需求,那么数据传输会通过主机。(注意,我们相信这些扩展将地址直接设备间通信的挑战;然而,这样的直接沟通也需要必要的硬件的支持。我们的评估平台没有满足硬件需求;因此,我们还没有定量评估这些扩展的利益,我们将作为未来工作的一部分)。

5.2。实现策略

我们讨论实现扩展部分5.1在我们OpenUH编译器。我们的实现是基于pthreads + CUDA的混合模型。CUDA 4.0及以后版本简化multi-GPU编程通过只使用一个线程来处理多个gpu。然而,在我们OpenACC multi-GPU扩展实现中,我们使用多个pthreads操作多个GPU和每个线程与GPU。这是因为内存分配和自由操作阻塞操作。如果一个程序员使用数据复制/ copyin / copyout在一个循环中,编译器将生成相应的数据内存分配和传递运行时api。由于内存分配是阻塞操作,不能并行执行多个gpu。CUDA代码避免这个分配内存的所有数据,然后进行数据传输。在OpenACC,然而,这是不可避免的,因为所有的运行时例程是由编译器生成的,这些例程不能随机放置的位置。我们的解决方案是创建一组线程,每个线程的上下文管理一个GPU在图所示5。这是一个基于任务的实现。假设我们有 最初gpu与CPU主机,主机创建 线程,每个线程都关联到一个GPU。每一个线程创建一个空先进先出(FIFO)任务队列,等待填充的主线程。根据指令类型和原始的deviceid条款OpenACC指令带注释的程序,编译器生成任务队列请求主线程。这里的任务意味着任何命令发布的主机和主机上或在设备上执行。例如,内存分配、内存免费的,数据传输,内核启动,设备间通信,所有这些,都是不同的任务类型。

算法8包括任务结构的定义和线程控制GPU(参见GPU线程)。只有通过GPU执行线程的任务。一个任务可以同步或异步主线程。在当前实现中,大多数任务都是异步的,除了设备内存分配,因为设备地址从一个临时参数传递结构,因此GPU的线程必须等待完成。每个GPU线程管理GPU上下文,一个任务队列,和一些数据结构,以便与大师沟通线程。本质上这仍然是主/从模型和GPU线程是工人。算法67显示详细的实现工作线程和主线程,分别。

(1)函数WORKER_ROUTINE
(2)创建上下文相关的GPU
(3)pthread_mutex_lock (⋯)
(4)context_created + +;
(5)
(6)pthread_cond_wait (⋯)等到所有线程创建上下文
(7)结束时
(8)pthread_mutex_unlock (⋯)
(9)如果 然后
(10)pthread_cond_broadcast (⋯)
(11)如果
(12)使对等访问所有设备之一
(13)(1)
(14)
(15)
(16)
(17)如果 然后
(18)
(19)同步GPU上下文上下文被阻塞直到设备
前完成所有要求的任务
(20)pthread_exit(空)
(21)如果
(22)结束时
(23)cur_task = cur_thread queue_head;获取任务从队列头
(24)cur_thread queue_size−−;
(25)如果 然后
(26)cur_thread queue_head =零;
(27)cur_thread queue_tail =零;
(28)其他的
(29)cur_thread queue_head = cur_task 下一个;
(30)如果
(31)pthread_mutex_unlock (&cur_thread queue_lock);
(32)cur_task 常规(无效 )cur_task args);   执行这个任务
(33)结束时
(34)结束函数

(1)函数ENQUEUE_TASK_XXXX
(2)分配内存和填充任务参数
(3)分配内存并填充任务
(4)pthread_mutex_lock (&cur_thread queue_lock)
(5)如果 然后把任务分成FIFO队列
(6)cur_thread queue_head = cur_task;
(7)cur_thread queue_tail = cur_task;
(8)pthread_cond_signal (&cur_thread queue_ready);信号队列非空的工人和任务是准备好了
(9)其他的
(10)cur_thread queue_tail 下一个= cur_task;
(11)cur_thread queue_tail = cur_task;
(12)如果
(13)cur_thread queue_size + +;
(14)pthread_mutex_unlock (&cur_thread queue_lock);
(15)如果 然后如果任务是同步的
(16)pthread_mutex_lock (&cur_thread queue_lock);
(17) 等到这个任务就完成了
(18)pthread_cond_wait (&cur_thread work_done, &cur_thread queue_lock);
(19)结束时
(20)pthread_mutex_unlock (&cur_thread queue_lock);
(21)如果
(22)结束函数

typedef struct _task_s
{
int类型;/ /任务类型(例如内存分配和内核启动,等等)。
无效 ( 常规)(空 );/ /程序的任务
_work_args 参数;/ /指向任务参数
int work_done;/ /显示任务是否完成
int异步;/ /是否异步任务
struct _task_s 下一个;/ /任务队列中的下一个任务
}_task;
类型定义结构体
{
int摧毁;/ /是否摧毁了这个线程
int queue_size;/ /任务队列的大小
pthread_t线程;/ /线程的身份
context_t 上下文;/ / GPU上下文与此相关的线程
int context_id;/ / GPU上下文id
_task queue_head;/ / FIFO的任务队列
_task queue_tail;/ / FIFO任务队列的尾部
pthread_mutex_t queue_lock;
pthread_cond_t queue_ready;/ /任务队列非空和准备好了
pthread_cond_t work_done;
pthread_cond_t queue_empty;
}_gpu_thread;

使设备间通信,必须使这种对等访问明确,这要求所有工作线程创建了GPU上下文。首先每个工人创造了上下文相关的GPU,然后等待,直到所有工人创造了GPU上下文。工人,是最后一个创建上下文将广播给所有工作线程,这样他们就可以开始启用对等访问。工人进入一个无限循环,等待传入的任务。当FIFO任务队列中的任务是准备好了,它将从队列中获取任务负责人和执行这个任务。没有任务时,工人只是睡觉节省CPU资源。当主人把一个任务FIFO队列的一个工人,工人,它将信号队列非空和任务是准备好了。如果主通知职工被摧毁,工人将完成所有未决任务,然后退出(参见算法6)。

5.3。基准的例子

在本节中,我们将讨论如何端口章节中讨论的一些基准4使用OpenACC扩展而不是使用混合模型。编制的程序使用该指令OpenUH编译器”-fopenacc nvcc,拱= sm_35 -fmad = false”旗帜。我们也比较性能与CUDA的版本。所有CUDA代码编译使用“o3拱= sm_35 -fmad = false”旗帜。

算法9显示了一个代码片段multi-GPU实现矩阵乘法的使用提出OpenACC扩展。使用该方法,用户仍需要明确的问题分割成不同的设备。这是因为如果有任何设备之间的依赖,编译器很难做这样的分析和管理数据通信。完全独立的循环,我们可能会进一步自动化问题分区编译器作为未来的工作的一部分。图6使用不同的模型显示了性能比较。我们可以看到手工CUDA版本和OpenACC扩展版本的性能远优于混合模型。帽编译器似乎根本就没有表现良好使用混合模型实现。的性能提出OpenACC扩展版本是最好的,它是非常接近CUDA的代码进行了优化。这有几个原因。首先,循环翻译机制从OpenACC CUDA在不同的编译器都是不同的。循环翻译意味着翻译从OpenACC嵌套循环CUDA并行内核。在翻译步骤中,在OpenUH OpenACC实现编译器使用冗余的执行模型不同OpenACC之间没有同步并行帮派和向量。然而,PGI编译器使用另一个执行模型加载一些标量变量在帮派并行共享内存,然后向量线程获取共享内存。详细的比较这两个循环之间的翻译机制是解释29日]。OpenUH编译器不需要做那些不必要的共享内存存储和加载操作,因此减少了这些开销。第二,我们发现帽OpenUH编译器使用翻译类似的循环机制。然而,它的性能还不如OpenUH编译器。可能的原因是,它已经nonefficient运行时库的实现。因为帽子本身并不提供OpenMP的支持,它需要复杂的运行管理与OpenMP其他CPU运行时编译器。这一结果表明我们的方法的有效性,不仅简化了multi-GPU实现还保持高性能。

f或(d = 0;d < num_devices;d + +)
{
块= n / num_devices;
开始= id 块;
结束= (id + 1) 块;
# pragma acc数据copyin (A(开始 n: n])
copyin (B(0:n n])
copyout (C(开始 n: n])
的deviceid (d)
{
# pragma acc平行的deviceid (d)
num_gangs (32)vector_length (32)
{
# pragma acc循环帮派
(我=开始;我<结束;我+ +){
# pragma acc循环向量
(j = 0;j < n;j + +){
浮动c = 0.0 f;
(k = 0;k < n;k + +)
c + =( n + k] B(k n + j];
C( n + j]= c;
}
}
}
}
(d = 0;d < num_devices;d + +){
# pragma acc等设备(d)
}

我们还端口2 d热方程使用提出的gpu OpenACC指令扩展。在代码级别,用户不需要使设备间通信的主机了;相反,更新同行指令可以用来减少代码复杂性,因此提高实施效率。算法10显示了详细multi-GPU实现代码使用OpenACC扩展和图7这个实现图形解释道。对比图4使用混合模型,很明显看到,设备之间的数据传输是要简单得多。图8使用不同的模型显示了性能比较。混合模型的性能版本使用帽编译器没有显示在这里因为它太慢了,也就是说,大约5 x比PGI慢的性能。当网格大小 ,OpenACC版本的执行时间大约是60秒的速度比混合模型和它接近的CUDA的代码进行了优化。我们注意到,几乎没有性能损失与我们提出的指令扩展。

f或(d = 0;d < num_设备;d + +){
# pragma acc (temp1_h copyin输入数据(d 乔治。:(行+ 2) 乔治。])设备(d)
# pragma acc (temp2_h copyin输入数据(d 乔治。:(行+ 2) 乔治。])设备(d)
}
(istep = 0;istep < nstep;istep + +){
(d = 0;d < num_devices;d + +)
step_kernel_ (ni + 2, + 2行,tfac temp1_h + d LDA, temp2_h + d LDA)
}
/ 等待完成内核计算 /
(d = 0;d < num_devices;d + +){
# pragma acc等设备(d)
}
/ 晕数据交换 /
(d = 0;d < num_devices;d + +){
如果(d > 0){
# pragma acc更新(temp2_h同行(d 乔治。:乔治。])to_device (d)
从(temp2_h(d 乔治。:乔治。])from_device (d 1)
}
如果(d < num_devices - 1){
# pragma acc更新(temp2_h同行((d + 1) LDA + LDA:乔治。])to_device (d)
从(temp2_h((d + 1) LDA + LDA:乔治。])from_device (d + 1)
}
}
/ 交换,数据的指针 /
temp_tmp = temp1_h;
temp1_h = temp2_h;
temp2_h = temp_tmp;
}
(d = 0;d < num_devices;d + +){
# pragma acc copyout出口数据(temp1_h((d 行数+ 1) 乔治。: 乔治。])的deviceid (d)
}
(d = 0;d < num_devices;d + +){
# pragma acc等设备(d)
}

6。结论和未来的工作

本文探讨了multi-GPU在单个节点的编程策略使用混合模型,OpenMP和OpenACC。我们证明我们的方法的有效性通过探索三个应用程序不同的特点。在第一个应用程序有不同的内核,每个内核是派往一个GPU。第二个应用程序有一个很大的工作量,是分解为多个小subworkloads,之后每个subworkload将GPU。与前两个由完全独立的应用程序工作负载在不同的gpu,第三个应用程序都有一些不同的gpu之间的沟通。我们评估了在multi-GPU混合模型与这三个应用程序,注意到合理的性能改进。基于经验聚集在这个过程中,我们提出了一些扩展OpenACC multi-GPU为了支持。通过使用该指令扩展,我们可以简化multi-GPU编程,但仍获得更好的性能比混合模型。最重要的是,优化的性能与手动CUDA的代码。

利益冲突

作者宣称没有利益冲突有关的出版。

确认

作者要感谢帽来帮助他们理解它的软件基础设施。作者还要感谢奥斯卡埃尔南德斯为他S3D代码为他的课堂讲稿和格雷厄姆Pullan热传导,帮助他们更好地理解应用程序。

引用

  1. CUDA,http://www.nvidia.com/object/cuda_home_new.html
  2. OpenCL标准,http://www.khronos.org/opencl
  3. HMPP指令参考手册(3.1 HMPP工作台),2015年,https://www.olcf.ornl.gov/wp content/uploads/2012/02/hmppworkbench _hmpp_directives_referencemanual.pdf——3.0
  4. 波特兰集团PGI加速器为Fortran和C编程模型波特兰集团,版本1.3,2010年。
  5. OpenACC标准,http://www.openacc-standard.org/
  6. 廖,y, b . r . de Supinski d·j·昆兰和b·查普曼”与openMP加速器模型,早期经验”OpenMP在低功率设备和加速器的时代:学报》第九届国际研讨会OpenMP IWOMP 2013年法案,澳大利亚,堪培拉9月16日至18日,2013年卷,8122在计算机科学的课堂讲稿施普林格,页84 - 98年,柏林,德国,2013年。视图:出版商的网站|谷歌学术搜索
  7. x, r·徐y, z Yun,和b·查普曼s•钱德拉塞卡兰”编译一个高级directive-based GPG-PUs编程模型,”并行计算的语言和编译器:26日国际研讨会,2013年LCPC, CA,圣何塞美国,2013年9月25 - 27日修改选定的论文120年,页105 -施普林格国际出版,2014年。视图:谷歌学术搜索
  8. r·雷耶斯Lopez-Rodriguez, j . j . Fumero和f . de Sande”accULL: OpenACC实现CUDA和OpenCL支持”2012年Euro-Par并行处理卷,7484在计算机科学的课堂讲稿施普林格,页871 - 882年,柏林,德国,2012年。视图:出版商的网站|谷歌学术搜索
  9. 李和j·s .检查者“早期评估有效的exascale计算机directive-based GPU编程模型,”学报为高性能计算国际会议,网络,存储和分析(SC的12),页1 - 11,IEEE计算机协会出版社,犹他州,盐湖城美国,2012年11月。视图:出版商的网站|谷歌学术搜索
  10. s . Wienke p Springer, c . Terboven和d最大经济产量,“OpenACC-first体验真实的应用程序中,”2012年Euro-Par并行处理卷,7484在计算机科学的课堂讲稿施普林格,页859 - 870年,柏林,德国,2012年。视图:出版商的网站|谷歌学术搜索
  11. b r, s•钱德拉塞卡兰查普曼,c . f . Eick”Directive-based科学应用程序编程模型比较,”SC的同伴:高性能计算、网络、存储和分析(SCC的12)IEEE,页1 - 9,犹他州,盐湖城美国,2012年11月。视图:出版商的网站|谷歌学术搜索
  12. a·哈特,r . Ansaloni和a .灰色”移植和扩展OpenACC大规模并行应用程序,GPU-accelerated超级计算机,“欧洲物理专题》杂志上,卷210,不。1,5-16,2012页。视图:出版商的网站|谷歌学术搜索
  13. j . m .几何、r . Sankaran和r .灌浆”组合使用OpenACC S3D变成一个exascale应用程序:一个方法搬到multi-petaflops,”学报为高性能计算国际会议,网络,存储和分析(SC的12),页1 - 11,IEEE计算机协会出版社,犹他州,盐湖城美国,2012年11月。视图:出版商的网站|谷歌学术搜索
  14. j·布埃诺,j .本书a杜兰et al .,“生产编程与omps GPU集群,”《IEEE 26日国际并行和分布式处理研讨会(IPDPS 12)IEEE,页557 - 568年,2012年5月。视图:出版商的网站|谷歌学术搜索
  15. c . Augonnet蒂博,r . Namyst和中国。Wacrenier“StarPU:一个统一的平台对异构多核任务调度架构,”并发性和计算:实践和经验,23卷,不。2、187 - 198年,2011页。视图:出版商的网站|谷歌学术搜索
  16. 和b·查普曼,r, s•钱德拉塞卡兰”探索编程multi-GPUs使用OpenMP和OpenACC-based混合模型,”IEEE学报》27日国际并行和分布式处理研讨会研讨会&博士论坛(IPDPSW 13)IEEE,页1169 - 1176年,剑桥,质量,美国,2013年5月。视图:出版商的网站|谷歌学术搜索
  17. s . Chatterjee m·格罗斯曼a . Sbirlea诉Sarkar,“与GPU工作窃取运行时系统动态任务的并行性,”语言和编译器的并行计算卷,7146在计算机科学的课堂讲稿施普林格,页203 - 217年,柏林,德国,2013年。视图:出版商的网站|谷歌学术搜索
  18. t . Komoda s古板,中村h和n . Maruyama”整合multi-GPU OpenACC编译器执行,”学报》第42届国际会议上并行处理(ICPP 13)IEEE,页260 - 269年,里昂,法国,2013年10月。视图:出版商的网站|谷歌学术搜索
  19. e . Ayguade n . Copty a杜兰et al .,“OpenMP的设计任务,”IEEE并行和分布式系统,20卷,不。3、404 - 418年,2009页。视图:出版商的网站|谷歌学术搜索
  20. 2012年技术报告指令附加加速器,http://openmp.org/wp/openmp-specifications/
  21. 帽OpenACC Parallism映射,2015,http://exxactcorp.com/index.php/software/prod_list/5
  22. r·徐x, y, b·查普曼,s•钱德拉塞卡兰“gpgpu并行操作循环,减少”程序的编程模型和应用程序在多核和冲击(PMAM 14)10 - 20页。ACM,纽约,纽约,美国,2007年。视图:出版商的网站|谷歌学术搜索
  23. 英伟达开普勒GK110架构白皮书,2014,http://www.nvidia.com/content/PDF/kepler/NVIDIA-Kepler-GK110-Architecture-Whitepaper.pdf
  24. j·h·陈,a . Choudhary b . de Supinski et al .,“Terascale湍流的直接数值模拟使用S3D燃烧,“计算科学与发现,卷2,不。1,文章ID 015001, 2009。视图:出版商的网站|谷歌学术搜索
  25. k .清单j . Meredith j .检查者j . Chen r .灌浆和r . Sankaran“加速S3D: GPGPU的案例研究,”Euro-Par 2009 -并行加工车间卷,6043在计算机科学的课堂讲稿施普林格,页122 - 131年,柏林,德国,2010年。视图:出版商的网站|谷歌学术搜索
  26. o·埃尔南德斯,w .叮,b·查普曼c . Kartsaklis r . Sankaran r·格雷厄姆,“经验与高级编程指令将应用程序移植到gpu,”面对Multicore-Challenge二世卷,7174在计算机科学的课堂讲稿施普林格,页96 - 107年,柏林,德国,2012年。视图:出版商的网站|谷歌学术搜索
  27. g . Pullan“剑桥cuda课程2009年5月25日- 27日,http://www.many-core.group.cam.ac.uk/archive/CUDAcourse09/视图:谷歌学术搜索
  28. 克雷C和c++参考手册,2014,http://docs.cray.com/books/s - 2179 81/s - 2179 - 81. - pdf
  29. r·徐m . Hugues h . Calandra b·查普曼,s•钱德拉塞卡兰“移民对GPU加速基尔霍夫使用指示,”学报第一车间对加速器编程使用指令(WACCPD 14),页37-46,IEEE 2014。视图:出版商的网站|谷歌学术搜索

版权©2015 Rengan徐等。这是一个开放分布式下文章知识共享归属许可,它允许无限制的使用、分配和复制在任何媒介,提供最初的工作是正确引用。


更多相关文章

PDF 下载引用 引用
下载其他格式更多的
订单打印副本订单
的观点2405年
下载740年
引用

相关文章