OpenACC指令适不适合我的程序吗?

感谢您对指令编译器感兴趣。这个文档将会真正帮助你理解您的代码是否可以从PGI加速编译器上获得好处,以及如何在GPU上使用这些指令。

对于NVIDIA GPU不得不知道的两件事情

1. NVIDIA GPU可以并行使用数百个计算内核来进行大规模海量数据计算。

2. 当数百个内核进行几十万甚至上百万计的并行执行线程时,NVIDIA GPU的性能会最佳。

将Amdahl定律应用于你的代码
了解您的应用程序运行时配置文件是必不可少的,这决定了这些GPU上的指令是否适合您。如果应用程序运行时不是由数据密集型计算占主导,那么GPU是不适合你。但是,如果应用程序运行时是由一些计算密集型部分消耗,那么GPU显著提速。

<IGNORE_JS_OP>什么程序适合指令.jpg

 

尽管GPU的显著加速了第一个应用程序的并行部分,但运行时(run-time)的性能只提高40%,因为非并行的部分相对大。第二个应用程序GPU加速明显,因为并行部分支配初始运行时,GPU可以对整个应用程序的性能产生重大影响。



可以用指令的代码结构

对于PGI指令,并行表示的是并行循环。一个适合于GPU指令的程序上,将有一个或多个具有非常大的总迭代计数的并行循环。如果有一个单一的数千迭代的并行循环,你的代码可以有效地利用GPU数百个内核的优势。如果循环限制小,嵌套并行循环是必要的,以确保有足够的并行。

提示#1

循环体可以相对较大,运行数百甚至上千行嵌套循环体和复杂的表达式,然而循环限制必须为规则的


至少有一些将要被加速的循环必须是完全的数据并行,这意味着没有同步,或者说迭代之间不会相互依赖.有一些嵌套里将要被加速的循环可以要求有限的同步,只要他们在传统意义上是可以矢量化的,比如reduction循环可以被加速.
Hint #2
完全的数据并行= 没有同步或者迭代间的相互依赖


不适合用指令的代码结构

不适合用PGI指令进行GPU加速的代码区和循环包括:

-非基于循环、面向对象的或分支密集型代码

-不是并行化或向量化的循环

-不直接进行内存访问的循环

-条件循环会产生重大分歧的代码路径

-执行非结构化积累(unstructured accumulations)的循环(简单结构化积累诸如dot产品是OK的)

-其源代码的预编译库中的函数调用的循环是PGI Accelerator编译器不可见的。

-有I / O语句的循环

-循环里有分支循环进入或离开,或有返回语句。

-有Fotran STOP语句的循环

 

强烈推荐的编码准则

如果一个应用程序在源代码中有一些独立的计算密集的部分,它更容易加快在GPU上。如果应用的性能分布比较均匀(大量独立函数中每个都占了很小的比例),就需要访问大部分源码,而且可能适用于利用指令对这些源码进行加速.

Hint #3

对于性能稳定的应用程序,利用PGI加速编程模块的deviceresident data功能可以通过内核,甚至主机子程序边界在设备内存里保留大的数据结构

下面是利用CFortran进行编程的通用准则:

1.尽量避免计算数组索引(index)

2. 用简单的表达式作为数组的下标

3. 在将卸载的代码区域里所有函数的调用必须自动被PGI加速编译器内联,或者被程序员手动内联。

4. 条件语句是OK的,但要警惕分支语句。

5.将要卸载的循环必须有规则的循环限制,以及有不变的行程记数

6.在C里,循环只能用于以下数据类型:整数、浮点、双精度或者结构体(嵌套的数据结构不能卸载到GPU

7.在C里,用于在循环里访问数组的指针,必须被C99 restrict声明

 

Hint #4

在C语言里通常在单精度计算里,如果没有将常量定义成双精度的(比如,3.14159f),就会作为字面常量(如:3.14159),在这种情况下,标准C需要常量被当作成双精度,而且跟它相关的计算都需要变成双精度。

在C语言中,一个常见的语句是把一个变量保存在一个标量里,为了后面重复使用.例如,你没有这些写:

  for( i = 0; i < n-1; ++i ){

   b = a + a[i+1];

  }

 

而是,你可能试图使用一个标量在循环中提取一个数组

  x = a[0];

   for( i = 0; i < n-1; ++i ){

     y = a[i+1];

     b = x + y;

   x = y;

  }

这样的一个微优化在C编程里很常见,但是第二个公式对于标量变量X有一个独立的循环。X值在一个迭代中被指派,然后用到下一个迭代中,这样这些迭代就不再是独立的。原始循环原本是完全并行的,这样问题就不是在算法,而是程序使用的编程风格。

Hint #5

在移植C代码,你可能碰上上面这个例子(如上述),可以有效地利用指令改变编码风格。如需例子看到http://www.pgroup.com/lit/articles/insider/v1n2a1.htm

Fortran里,只有嵌套循环可以加速——没有array syntax, 没有 reshape(), 通常,最好避免外来F90/F2003 功能。循环加速只能对于这些数据类型:整数、real、双精度、complex, double complexderived types, allocatables, 以及CUDA数据。指针属性是不支持的,指针数组需要定义,但是指针关联是不会在GPU内存里保留。支持大多数标量运算和超越的内在函数,MAX(),SUM()

那么现在做什么?

你现在已经确认您程序中计算密集的部分可以用指令来进行GPU加速,那么现在就开始吧.

  一个完整的PGI Accelerator指令语法规范,请参阅
http://www.pgroup.com/lit/whitepapers/pgi_accel_prog_model_1.3.pdf

posted @ 2012-04-10 22:30  gpus  阅读(1285)  评论(0编辑  收藏  举报
[url=http://weibo.com/2640510102?s=6uyXnP][img]http://service.t.sina.com.cn/widget/qmd/2640510102/1522e446/1.png[/img][/url]