4

Microsoft PPL ライブラリと並列プログラミング全般について質問があります。FFTW を使用して、64 x 64 x 64 FFT と逆 FFT の大規模なセット (100,000) を実行しています。現在の実装では、並列 for ループを使用し、ループ内でストレージ配列を割り当てます。これらのケースでは、CPU 使用率が約 60 ~ 70% しか上がらないことに気付きました。(これは、私がテストした FFTW によって提供される組み込みのスレッド化された FFT よりも優れた使用率であることに注意してください)。fftw_malloc を使用しているため、完全な使用を妨げている過剰なロックが発生している可能性はありますか?

これに照らして、メイン処理ループの前に各スレッドにストレージ配列を事前に割り当てて、ループ自体の中でロックが不要になるようにすることをお勧めしますか? もしそうなら、MSFT PPL ライブラリでこれがどのように可能になるのでしょうか? 私は以前に OpenMP を使用していました。その場合、提供された関数を使用してスレッド ID を取得するのは簡単です。ただし、PPL ドキュメントで同様の関数を見たことがありません。

4

2 に答える 2

2

まだ誰も投稿していないので、私はこれに答えています。

強力なロックが必要な場合、Mutex(e)はパフォーマンスに大きな打撃を与える可能性があります。さらに、大量のメモリ(再)割り当てが必要な場合は、パフォーマンスが低下し、メモリ帯域幅に制限される可能性があります。あなたが言ったように、後のスレッドが動作する事前割り当ては便利です。ただし、これには、スレッド数が固定されていることと、すべてのスレッドでバランスの取れたワークロードを分散することが必要です。

PPLのthread_id関数に関しては、Intel-TBBについてしか話せませんが、PPLとかなり似ているはずです。TBB(そしてPPLも)はスレッドについて直接話しているのではなく、タスクについて話していると思います。TBBの目的は、これらの基礎となる詳細をユーザーから引き離すことであり、したがって、thread_id関数を提供しません。

于 2012-04-04T08:39:36.867 に答える
1

Concurrency::combinablePPL を使用すると、スレッドごとに割り当てられたメモリを含む構造体を保持するために を 使用することで、多くの割り当てを行うアプリケーションで良好なパフォーマンスが得られました。

実際、事前に割り当てる必要はありません。組み合わせ可能な変数の値を確認して、->local()null の場合は割り当てることができます。次にこのスレッドが呼び出されると、すでに割り当てられています。

もちろん、次のようなものを使用して実行できるすべてのタスクが完了したら、メモリを解放する必要があります。

combine_each([](MyPtr* p){ delete p; });
于 2012-11-04T16:34:27.620 に答える