使用Openmp进行前缀扫描的流压缩(或阵列打包)

时间:2014-11-05 12:43:17

标签: fortran openmp thrust prefix-sum stream-compaction

我使用openmp来并行化我的代码。我有一个原始数组:

A=[3,5,2,5,7,9,-4,6,7,-3,1,7,6,8,-1,2]

和标记数组:

M=[1,0,1,0,0,0,1,0,0,1,1,0,0,0,1,1]

使用数组M我可以压缩这个打包数组中的原始数组:

A=[3,2,-4,-3,1,-1,2]

我想使用多线程方法解决这个问题。图书馆' Thrust' for C ++解决了这个问题,但我无法为Fortran找到类似的工具。 是否有一个图书馆,比如“推力”和#39;对于C ++,我可以用来执行流压缩? 或者,是否有一种算法,我可以用fortran和openmp自己编写,以解决这个问题?

1 个答案:

答案 0 :(得分:1)

  
    

是否有一个库,比如C ++的'推力',我可以用它来执行流压缩?

  

从Fortran调用推进例程应该不那么困难(如果你愿意写一点C ++代码)。此外,推力可以针对OMP后端而不是GPU后端。

  
    

或者,是否有一种算法我可以使用fortran和openmp自行编写,以解决这个问题?

  

基本并行流压缩算法如下。我们假设最初在数据数组中为每个元素分配了一个线程。

  1. M阵列上执行parallel prefix sum (inclusive scan)

     M=[1,0,1,0,0,0,1,0,0,1,1,0,0,0,1,1]
    sM=[1,1,2,2,2,2,3,3,3,4,5,5,5,5,6,7]
    
  2. 然后每个线程将检查M数组中的元素,如果该元素为非零,它会将A数组中的相应元素复制到输出数组(我们称之为O):

     M=[1,0,1,0,0,0, 1,0,0, 1,1,0,0,0, 1,1]
    sM=[1,1,2,2,2,2, 3,3,3, 4,5,5,5,5, 6,7]
     A=[3,5,2,5,7,9,-4,6,7,-3,1,7,6,8,-1,2]
     O=[3,  2,      -4,    -3,1,      -1,2]
    
  3. 如果您在OMP中执行此操作,则在步骤1和步骤2之间需要OMP屏障。步骤2中的工作相对简单且完全独立,因此您可以使用OMP并行执行循环,并打破工作以任何你想要的方式。第1步将很复杂,我建议按照您和我链接的章节中提供的大纲进行操作。那里的OMP代码将需要各种障碍,但可以并行化。

    正如评论中已经提到的,如果这是你想要并行化的唯一的工作,我不推荐使用GPU,因为将数据传输到GPU或从GPU传输数据的成本可能会超过您可能产生的任何并行执行时间的好处。但正如我已经提到的,推力可以针对OMP实现而不是GPU实现。值得一试。

    关于来自fortran的推力,你需要的大部分是here。这无疑是CUDA fortran,但唯一的区别应该是不使用device属性,并使用thrust :: host_vector而不是thrust :: device_vector(至少,开始使用)。