【问题标题】:SIMD instructions with condition copy带有条件副本的 SIMD 指令
【发布时间】:2016-08-28 21:10:36
【问题描述】:

我有一个看起来像这样的热点。在这里收集某种矢量会很好......关于如何让编译器喜欢这个的任何建议?

        do ii = 1, N
           if (diff(ii) .le. M ) then
              i = i0 + ii - 1
              rbuf( irb ) = i 
              irb = irb + 1               
           end if
        end do

使用 ifort 16.0.2 我的 opt 报告看起来像

LOOP BEGIN at code.f(197,13)
   remark #25084: Preprocess Loopnests: Moving Out Store    [ code.f(203,13) ]
     remark #15344: loop was not vectorized: vector dependence prevents vectorization
     remark #15346: vector dependence: assumed FLOW dependence between irb line 201 and irb line 200
     remark #15346: vector dependence: assumed ANTI dependence between irb line 200 and irb line 201
     remark #15346: vector dependence: assumed ANTI dependence between irb line 200 and irb line 201
     remark #15346: vector dependence: assumed FLOW dependence between irb line 201 and irb line 200
     remark #25439: unrolled with remainder by 2
     remark #25015: Estimate of max trip count of loop=1600
  LOOP END

这里是小测试程序

program vect

integer :: ii, i0, irb
integer, parameter :: N=32
integer, parameter :: M=8
integer, dimension(N) :: diff
integer, dimension(2*N) :: rbuf

rbuf = 0

!only some values of diff will meet condition
!could be random
do ii=1, N
   diff(ii) = ii
end do

!from an outer loop
i0=1003

!this is code for filling up a buffer for an expensive vectorized
!subroutine with full vectors, irb < 2*N
irb=3

do ii = 1, N
   if (diff(ii) .le. M ) then
      i = i0 + ii - 1
      rbuf( irb ) = i 
      irb = irb + 1               
   end if
end do


!check 
do ii = 1, 2*N
   write(*,*) ii, rbuf(ii)
end do

end

【问题讨论】:

  • diff 是函数还是数组?你能创建一个最小的可编译示例来玩吗?
  • @AlexanderVogt 现在举个例子
  • 您正在复制一个数组,根据条件过滤掉一些元素?请参阅this question,以及 SSE 和 AVX2 答案(以及 AVX512 答案)。向量化是可能的,但 C 编译器不会为你做这件事。可能也不是 Fortran 编译器。您将需要与 C 内在函数等效的东西,或者只调用 C 或 asm 函数。

标签: fortran vectorization intel simd


【解决方案1】:

根据目标架构,我能够让编译器使用指令进行矢量化。

!CDIR$ IVDEP
do ii = 1, N
 if (diff(ii) .le. M ) then
   i = i0 + ii - 1
   rbuf( irb ) = i 
   irb = irb + 1               
 end if
end do

-xMIC-AVX512-mmic 将为这些架构提供向量指令。例如

vpcompressd %zmm0, -4+vect_$RBUF.0.1(,%rax,4){%k1}      #29.15 c1

对于 AVX2,我认为正如@Peter Cordes 在他的评论中所建议的那样,人们已经求助于内在函数/asm,但很高兴知道编译器可以在未来解决这个问题。

【讨论】:

  • 酷,我很高兴编译器足够聪明,可以使用vpcompressd / vcompressps。该指令似乎正是为这个用例而设计的。现在编译器可以识别这种模式并使用vcompress,也许他们会学习使用 AVX2 和 BMI2 进行自动矢量化。 (我动态生成 shuffle 掩码的技术比标量更快,根本不需要查找表,也不需要太多的代码大小。:)
猜你喜欢
  • 2016-11-04
  • 2017-01-09
  • 2021-06-29
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多