0

我正在使用 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]

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

4

1 回答 1

1

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

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

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

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

  1. 对数组执行并行前缀求和(包含扫描) :M

     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]
    

如果您在 OMP 中执行此操作,则需要在步骤 1 和步骤 2 之间设置 OMP 屏障。步骤 2 中的工作相对简单且完全独立,因此您可以使用 OMP 并行执行循环,并以任何方式分解工作你希望。第 1 步会很复杂,我建议按照你和我链接的章节中提供的大纲进行操作。那里的 OMP 代码将需要各种障碍,但可以并行化。

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

关于 fortran 的推力,您需要的大部分内容都在这里。这无疑是 CUDA fortran,但唯一的区别应该是不使用设备属性,并使用推力::主机向量而不是推力::设备向量(至少,开始使用)。

于 2014-11-08T04:48:46.640 回答