http://opencamel.zxq.net/?p=34
HMPP与PGI编程模型对比
p { margin-bottom: 0.08in; }
注:个人总结,如果错误,请及时指正。
|
| HMPP | PGI |
基本信息 | 所属分类 | 针对加速器,采用类 OpenMP 制导的语言模型 | |
公司 | CAPS | PGI | |
组成 | Host 编译器 + 加速器代码生成器( 显式 + 可选 ) + 运行时系统 | Host 编译器 + 加速器代码生成器( 隐式 + 必须使用 ) + 运行时系统 | |
编译器源语言支持 | C/Fortran | C/Fortran | |
编译基本框架 | 源源翻译(显式) + 运行时 | 源源翻译(隐式) + 运行时 | |
支持的应用类型(针对代码生成器部分) | 大规则数据并行 规则数据访问 | 大规则数据并行; 规则数据访问; 受限于编译器分析,只能处理长方形迭代空间的循环 | |
支持的异构计算平台 | 支持同时支持多种 GPU 及多块 GPU | 不支持多个同一种加速器,不支持不同种类的加速器 | |
作为加速的代码粒度 | 函数( Codelet ); 区域( Region ) [2.3 版本支持 ] | 包含循环的结构的程序块( Compute region ) | |
加速器代码生成器支持的目标代码 | CUDA for Nvidia GPU CAL/IL or Brook for ATI/AMD GPU C for debugging purpose SSE for SSE vectorization CELL for IBM Cell processors (limited support) OpenCL | CUDA for Nvidia GPU | |
流式编程的封装 | Kernel 执行所需数据 | 由作为 Codelet 的函数的参数决定 | 通过 region/data region 指定所需变量或数组区域;或直接由编译器自动分析。 |
Kernel 间共享数据 | 在同一个设备上连续执行的 codelet 可以通过实参映射实现数据重用; 可以通过 RESIDENT+GROUP 制导,实现在组内 codelet 间的数据共享 | 可以通过 data region 来共享不同 Region 中的数据 | |
Kernel 执行所需数据的属性 | 分为 in,out,inout ,通过设置 callsite 制导的属性 | 可以在 data region 或 region 的 copyin,copyout,copy 子句中设置 | |
Kernel 执行的数据存储位置 | 作为参数传递的数据都存放在 Device Memory 中; Kernel 函数体的其他定义的变量也存储在 Device Memory 中,不需要用户显示处理 | 可以通过 data region/region 制导的 copyin,copyout,copy 子句将所需的数据存放在 Device Memory 中; 通过 local 子句,将 region 中所使用的不需要与 Host 主存同步的数据分配到 Device Memory 中。 | |
Kernel 定义 | 在所选函数的外部加 codelet 制导 | 对结构化的程序块,使用 code region 或 code region for 制导 | |
Kernel 调用 | 在作为 Codelet 的函数调用点处 callsite 制导 | Kernel 的定义点即为调用点 | |
Kernel 执行位置 | 通过指定 callsite 制导的 target 属性指定;当一个函数调用点存在多个 callsite 制导时,由运行时根据当前系统的动态执行环境(设备可用性及设备资源的可用性)选择其中一个设备执行 | 当前版本仅支持一个支持 CUDA 的 GPGPU | |
是否支持 Kernel 的条件执行 | 支持,通过设置 codelet 制导的 condition 子句(用户可以设置条件控制 codelet 在何种设备上执行,但具体的执行还是需要由运行时系统进行判断) | 支持,通过设置 region 制导的 if 子句(满足条件则在 GPU 上执行,不满足则由 HOST 执行) | |
| Fall back to CPU | 支持,当运行时系统判断一个 Codelet 所有可能用于执行的设备不可用时,交给 CPU 执行。 | 支持,如果 region 的 if 子句不满足,则该 region 的代码将由 CPU 执行。 |
并行性表达和映射 | 执行模型 | 每个 Codelet 的执行采用 Fork-join 模式 | 每个 Region 代码的执行采用 Fork-join 模式 |
包含的并行性 | 两层并行性支持(宏观)。 1 )支持多块设备,包含 Codelet 之间的 任务并行(不规则并行,能够表达出 DAG ,但不能表达树) 2 ) Codelet 内的 数据并行(规则并行) | 一层并行支持(宏观)(当前版本) Region/Region for 制导所标注的代码的 数据并行(规则并行) | |
并行性的表达 | 第一层并行( Codelet 间并行)通过以 hmpp 开头的制导表达; 第二层并行: 通过 hmpp cg 制导表达;或直接由用户书写加速器代码表达 | 通过用户给出 region for/for 制导及其相关循环调度的子句( host,parallel,seq,vectort )表达; | |
并行映射 | 两层并行一层映射 第一层:根据设备可用性和设备资源可用性映射 Codelet 到执行设备; 第二层:由用户手工书写加速器程序,映射到加速器的线程;或给出制导,由代码生成器负责映射 Codelet 代码到线程 | 一层并行一层映射 由于当前版本仅支持一个设备,故它不支持类 HMPP 的第一层并行及其映射; 它的一层并行的映射只能通过用户给出 region for/for 制导及其相关循环调度的子句( host,parallel,seq,vectort ),引导编译器映射要加速的代码区到加速器线程。 | |
映射时机及方式 | 第一层并行:动态 第二层并行:静态 | 静态 | |
存储布局的支持 | 支持 DSM | 不支持 | 不支持 |
数据一致性保证( host memory 与 acc memory ) [ 异构存储 ] | 用户通过显示使用数据相关制导( ALLOCATE,ADVANCEDLOAD ) 保证 | 用户通过显示使用 data region 或 region/region for 的数据子句保证 | |
加速器设备层次存储的利用 | 通过以 hmpp cg 开头的制导利用; 或由用户手工书写程序利用 | 通过 data region 或 region/region for 的数据子句,及 for 制导的 private/cache 子句 | |
数据与计算的亲和性表达 | 隐式表达 | 隐式表达 | |
同步与通信 | 加速代码同步支持 | 隐式同步; 异步执行 + 显示同步; | 隐式同步; |
分组支持 | 支持在同一设备上执行的 Codelet 分组,数据重用 | 隐式的分组,所有的 region 都在一个组内 | |
加速代码之间的通信 | 不支持 | 不支持 | |
优化程序性能 | 加速代码之间 | 对于 Codelet 级,手工优化相对容易,主要策略是 Codelet 间的通信优化。 1 )异步的数据传输,实现计算与通信的重叠 2 )通过 Codelet 组的概念及 RESIDENT 属性,处理全局共享数据【 resident data 】 3 )通过指定数据的只读属性,减少数据的传输次数【 constant parameter 】 4 )利用实参映射机制 , 实现连续在同一个设备上执行的 Codelet 之间的数据重用 | 相对于 HMPP ,由于不支持加速代码区域的异步执行且仅支持一个设备,除了 HMPP 中的异步数据的传输实现计算与通信的重叠外,其他优化都可以通过指定相关制导的子句实现。 |
加速代码之内 | 对于 Codelet 内部,如要采用编译制导 + 代码生成器的方案生成目标代码,这部分的优化,用户需要熟悉加速器编程,能够合理地给出相关制导的属性值,配合性能分析工具,才有可能获得好的性能。 当然,如果用户直接使用手工书写 Codelet 内的加速器代码,经过针对特定加速器结构的调优,可以获得非常好的性能,但违背了 HMPP 的减化用户编程的初衷。 | 由于只能由用户给出制导辅导加速器代码生成,因此,用户必须合理选择 for 制导的子句及其参数值。 | |
支持性能回馈( Performance feedback ) | 未知 | 支持 | |
运行时支持 | 并行性映射 | Codelet 到设备的映射,由运行时系统根据当前动态的执行环境中的设备可用性及设备资源的可用性完成。 | 静态映射,所有的 Region 依次映射到一个设备上执行 |
存储布局 | 运行时根据 Codelet 所需数据的属性,完成 Host-ACC 的数据传输 | 运行时根据 data region 或 region/region for 的数据子句,完成 Host-ACC 的数据传输 | |
总体评价 | 可编程性方面 | Codelet 级的制导基本覆盖了用于实现通讯优化的方法,包括数据预取,计算与通信的重叠, Codelet 间的数据重用等; 以 hmpp cg 开头的制导用于辅助代码生成器生成加速器代码,虽然统一使用了高层语言,保持了代码的可移植性,但是添加优化的制导方案其难度与手工书写 CUDA 代码相当。很多结构相关的优化需要由用户手工加入制导实现。 | 用户只需要考虑一个加速器的情况,用户面对的只是 data region/region/region for 制导的有限子句,更多的工作由编译器自动分析,受限于编译器分析的能力,很多情况下,编译器分析失败。但 PGI 提供了性能反馈信息,用于指导用户根 据提示信息手工变换 Region 代码,以利用编译器自动生成加速器代码。 但是性能反馈信息,基本上是编译方面的专业术语,一般用户可能难以理解。 |
侧重点 | 解决异构编程的整体框架 | 强依赖于编译分析协助用户并行化要在加速器上执行的代码,生成 CUDA 代码 | |
整体结构 | 比较灵活,用户有多种选择,可以自己书写加速器代码,利用 HMPP 简化程序部署;也可以给出制导,由代码生成器生成。 | 只提供一种方式,即由编译器为用户生成加速器代码。 | |
|