0

Intel TBB parallel_forを使用して、いくつかの計算を行うforループを高速化します。

tbb::parallel_for(tbb::blocked_range<int>(0,ListSize,1000),Calc);

CalcはクラスdoCalcのオブジェクトです

class DoCalc
{
vector<string>FileList;
public:
    void operator()(const tbb::blocked_range<int>& range) const{
    for(int i=range.begin(); i!=range.end();++i){
    //Do some calculations
    }
    }
    DoCalc(vector<string> ilist):FileList(ilist){}
};

約かかります。forループの標準シリアル形式を使用すると60秒。TBBのparallel_forを使用してジョブを実行する場合は20秒。の標準を使用する場合、私のi5CPUの各コアの負荷は約です。15%(Windowsタスクマネージャーによる)、非常に不均一で、約 parallel_forを使用すると、50%で非常に均一になります。

parallel_forを使用すると、さらに高いコア負荷を得ることができるのではないかと思います。grain_size以外のパラメータはありますか?forループ内の操作を変更せずにparallel_forの速度を上げるにはどうすればよいですか(ここでは//上記のコードサンプルでいくつかの計算を行います)。

4

3 に答える 3

1

粒度パラメーターはオプションです。グレインサイズが指定されていない場合、パーティショナーをアルゴリズム テンプレートに提供する必要があります。パーティショナーは、範囲のチャンクをガイドするオブジェクトです。auto_partitioner は、粒子サイズをヒューリスティックに選択する代替手段を提供するため、粒子サイズを指定する必要はありません。負荷分散のための十分な機会を提供しながら、オーバーヘッドを制限しようとするヒューリスティックな試み。

詳細については、tbb Web サイトにアクセスしてください。www.threadingbuildingblocks.org

于 2012-12-12T16:57:41.287 に答える
0

@Eugene Roader が既に提案したように、 auto_partitioner (TBB バージョン 2.2 のデフォルト) を使用して、範囲を自動的にチャンクすることをお勧めします。

tbb::parallel_for(tbb::blocked_range<int>(0,ListSize),Calc,tbb:auto_partitioner());

あなたの i5-CPU には 4 つのコアがあると想定しているため、並列化に特定のオーバーヘッドがある可能性があるため、3 (60 秒 => 20 秒) のスピードアップが得られます。1 つの問題は、3 つのスレッドで飽和している CPU のメモリ帯域幅の最大制限である可能性があります。または、標準のメモリ マネージャーを使用してスレッド間で同期する/同期する必要がある多くの割り当て/割り当て解除がある可能性があります。内側のループのコードをあまり変更せずにこの問題に対処する方法の 1 つは、スレッド ローカル アロケーターを使用することです。

vector<string,tbb:scalable_allocator<string>> FileList;

ループで使用される他のすべてのコンテナーに対しても tbb::scalable_allocator を試す必要があることに注意してください。これにより、並列化のスピードアップをコア数 4 に近づけることができます。

于 2013-02-22T23:48:07.403 に答える
0

あなたの質問への答えは、メモリアクセスとアルゴリズムの計算の比率にも依存します。大量のデータに対してほとんど操作を行わない場合、問題はメモリ バウンドであり、コアの負荷が制限されます。一方、少ないデータで多くの計算を行うと、改善の可能性が高くなります。

于 2013-02-14T14:13:40.743 に答える