Power8上的OpenMP SIMD

时间:2015-06-09 09:42:17

标签: openmp vectorization simd powerpc

我想知道Power8上是否有任何编译器(gccxlc等)支持Power8上的OpenMP SIMD结构?我试过XL(13.1),但我无法成功编译。可能它还不支持simd构造。

我可以用gcc 4.9.1编译(带有这些标志-fopenmp -fopenmp-simd-O1)。我把2个asm文件之间的差异。

我可以说gcc 4.9能够生成altivec代码吗?为了更好地优化,我应该做什么? (我试过-O3,限制治疗)

我的代码非常简单:

int *x, *y, *z;
x = (int*) malloc(n * sizeof(int));
y = (int*) malloc(n * sizeof(int));
z = (int*) malloc(n * sizeof(int));   

#pragma omp simd
for(i = 0; i < N; ++i)
  z[i] = a * x[i] + y[i];

生成的程序集在这里

  .L7:
  lwz 9,124(31)
  extsw 9,9 
  std 9,104(31)
  lfd 0,104(31)
  stfd 0,104(31)
  ld 8,104(31)
  sldi 9,8,2
  ld 10,152(31)
  add 9,10,9
  lwz 10,124(31)
  extsw 10,10
  std 10,104(31)
  lfd 0,104(31)
  stfd 0,104(31)
  ld 7,104(31)
  sldi 10,7,2
  ld 8,136(31)
  add 10,8,10
  lwz 10,0(10)
  extsw 10,10
  lwz 8,132(31)
  mullw 10,8,10
  extsw 8,10
  lwz 10,124(31)
  extsw 10,10
  std 10,104(31)
  lfd 0,104(31)
  stfd 0,104(31)
  ld 7,104(31)
  sldi 10,7,2
  ld 7,144(31)
  add 10,7,10
  lwz 10,0(10)
  extsw 10,10
  add 10,8,10
  extsw 10,10
  stw 10,0(9)
  lwz 9,124(31)
  addi 9,9,1
  stw 9,124(31)

GCC与-O1 -fopenmp-simd

.L7:
lwz 9,108(31)
mtvsrwa 0,9
mfvsrd 8,0
sldi 9,8,2
ld 10,136(31)
add 9,10,9
lwz 10,108(31)
mtvsrwa 0,10
mfvsrd 7,0
sldi 10,7,2
ld 8,120(31)
add 10,8,10
lwz 10,0(10)
extsw 10,10
lwz 8,116(31)
mullw 10,8,10
extsw 8,10
lwz 10,108(31)
mtvsrwa 0,10
mfvsrd 7,0
sldi 10,7,2
ld 7,128(31)
add 10,7,10
lwz 10,0(10)
extsw 10,10
add 10,8,10
extsw 10,10
stw 10,0(9)
lwz 9,108(31)
addi 9,9,1
stw 9,108(31)

为了澄清和理解细节,我还有一个应用程序是n ^ 2 nbody application。这次我的问题与这些编译器(gcc 4.9和XL 13.1)和架构(Intel和Power)有关。

我将所有代码放入gist https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-input-c输入代码input.c的完整版本

  1. Power8&amp; XLC - 它说“不是SIMD矢量化,因为它包含函数调用。(有sqrtf)”。这很合理。但是在asm代码中我可以看到xsnmsubmdp是正常的吗? (大会:https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-power8-xlc-noinnersimd-asm
  2. Power8&amp; gcc 我尝试用2种方式编译它(使用omp simd构造而不使用)。它改变了我的asm代码,这是正常的吗? (根据OpenMP,代码不应包含函数调用)(Assembilies:https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-power8-gcc-noinnersimd-asm&amp; https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-power8-gcc-innersimd-asm
  3. i74820K&amp; gcc 我用omp simd做了同样的测试,没有它。输出代码也不同。 FMA会影响此代码块吗? (Assembilies:https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-i74820k-gcc-noinnersimd-asm&amp; https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-i74820k-gcc-innersimd-asm
  4. 提前致谢

2 个答案:

答案 0 :(得分:3)

我现在无法访问基于Power的计算机,但是在x86上对AST转储程序进行的一些实验表明,只有在优化级别达到{{1}时,GCC 4.9.2才会开始生成SIMD代码},即以下选项应该做的伎俩:

O1

GCC 5.1.0也是如此。

另请注意,矢量化程序应用的成本模型可能会阻止它在某些情况下实际生成矢量化代码。有关如何覆盖该行为,请参阅-fopenmp-simd -O1 和类似选项here

答案 1 :(得分:3)

POWER Linux上的XL编译器目前仅支持OpenMP 4.0功能的子集。目前不支持SIMD构造功能,因此编译器将无法识别源代码中的构造。

但是,如果您正在寻找矢量化,那么好消息是,只要您使用至少以下优化选项,XL编译器就应该已经自动对您的代码进行矢量化

  

-O3 -qhot -qarch = pwr8 -qtune = pwr8

这些选项将启用high-order loop transformations以及POWER8特定的优化,包括循环的循环自动矢量化。

之后,你会看到一些VMX&amp;生成的汇编代码中的VSX指令类似于以下内容:

 188:   19 2e 80 7c     lxvw4x  vs36,0,r5
 18c:   84 09 a6 10     vslw    v5,v6,v1
 190:   10 00 e7 38     addi    r7,r7,16
 194:   10 00 a5 38     addi    r5,r5,16
 198:   40 28 63 10     vadduhm v3,v3,v5
 19c:   80 20 63 10     vadduwm v3,v3,v4
 1a0:   19 4f 66 7c     stxvw4x vs35,r6,r9
 1a4:   14 02 86 41     beq     cr1,3b8 <foo+0x3b8>
 1a8:   10 00 20 39     li      r9,16
 1ac:   19 4e 27 7d     lxvw4x  vs41,r7,r9
 1b0:   19 3e a0 7c     lxvw4x  vs37,0,r7

顺便说一句,您还可以使用-qreport选项从XL编译器获取优化报告。这将解释哪些循环被矢量化以及哪些循环不是由于什么原因。 e.g。

  

1586-542(I)循环(循环索引1,具有嵌套级别0和迭代计数   100)在test.c进行SIMD矢量化。

  

1586-549(I)test.c上的循环(循环索引2)不是SIMD   矢量化,因为数据依赖性阻止了SIMD矢量化。

希望这有帮助!