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++ 用のライブラリ 'Thrust' はこの問題を解決しますが、Fortran 用の同様のツールを見つけることができません。ストリーム圧縮を実行するために使用できる、C++ の「thrust」のようなライブラリはありますか? または、これを解決するために、fortran と openmp を使用して自分で作成できるアルゴリズムはありますか?

4

1 に答える 1

1

ストリーム圧縮を実行するために使用できる、C++ の「thrust」のようなライブラリはありますか?

Fortran からスラスト ルーチンを呼び出すことはそれほど難しくないはずです (C++ コードを少し書きたい場合)。さらに、推力は GPU バックエンドの代わりに OMP バックエンドをターゲットにすることができます。

または、これを解決するために、fortran と openmp を使用して自分で作成できるアルゴリズムはありますか?

基本的な並列ストリーム圧縮アルゴリズムは次のとおりです。最初は、データ配列の要素ごとに 1 つのスレッドが割り当てられていると想定します。

  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 並列 do ループを使用して、任意の方法で作業を分割できます。あなたが望む。ステップ 1 は複雑になるため、リンク先の章に記載されている概要に従うことをお勧めします。そこにある OMP コードは、途中でさまざまな障壁を必要としますが、並列化可能です。

コメントで既に述べたように、これが並列化したい唯一の作業である場合、GPU をお勧めしません。GPU との間でデータを転送するコストが、おそらく並列実行時間のメリットを上回るからです。発生します。しかし、すでに述べたように、スラストは GPU 実現ではなく OMP 実現をターゲットにすることができます。試してみる価値があるかもしれません。

Fortran からの推力に関して、必要なもののほとんどはここにあります。これは確かに CUDA fortran ですが、唯一の違いは device 属性を使用しないことと、thrust::device_vector の代わりに Thrust::host_vector を使用することです (少なくとも、開始するには)。

于 2014-11-08T04:48:46.640 に答える