1

STL remove_ifの並列バージョンを実行しようとしています。私が行ったことは、グローバル メモリにカウンターを作成し、各スレッドが 1 つの要素で動作するようにすることです。その要素がキーと等しくない場合は、結果の配列にコピーされ、アトミック加算によってカウンターによって決定されたインデックスが付けられます。頻繁なアトミック操作を避けるためのより良い代替手段はありますか?

スラスト ライブラリにも remove_if があることがわかりましたが、「thrust\detail\backend\cpp\remove.h」ディレクトリにあるソース コードについて非常に混乱しています。

template<typename ForwardIterator,
     typename InputIterator,
     typename Predicate>
ForwardIterator remove_if(ForwardIterator first,
                        ForwardIterator last,
                        InputIterator stencil,
                        Predicate pred)
{
// advance iterators until pred(*stencil) is true or we reach the end of input
while(first != last && !bool(pred(*stencil)))
{
    ++first;
    ++stencil;
}

if(first == last)
    return first;

// result always trails first 
ForwardIterator result = first;

++first;
++stencil;

while(first != last)
{
    if(!bool(pred(*stencil)))
    {
        *result = *first;
        ++result;
    }
    ++first;
    ++stencil;
}

return result;
}

これはエレメント除去を順番に行っているのではないでしょうか?

ご提案ありがとうございます。

4

1 に答える 1

2

独自の実装を展開するやむを得ない理由がない限り、Thrust remove_if() を使用することをお勧めします。Thrust は STL でモデル化されており、一般性に対する要件が類似している場合、Thrust のソース コードと非常によく似たコードを作成することになります。

Thrust のパフォーマンスが満足のいくものでない場合、Thrust コミュニティ (主要な作成者を含む) は、より良いパフォーマンスのためにコードを作成する方法について良い提案をしてくれるかもしれません。

それに失敗した場合 - 垂直アプリケーションがあり、Thrust が十分に高速でない場合 - 最後の手段としてスキャンベースの実装をロールバックします。アルゴリズムの 1 行の要約は、述語の逆で並列プレフィックス合計 (「スキャン」) を実行することです。保持する要素の出力インデックスは、スキャンの対応する要素によって指定されます。

于 2012-09-08T20:40:28.497 に答える