2

boost ライブラリを使用してコードをマルチスレッド化しようとしています。問題は、各スレッドがいくつかのグローバル変数にアクセスして変更する必要があることです。ミューテックスを使用して共有リソースをロックしていますが、プログラムがマルチスレッド化されていない場合よりも時間がかかります。共有アクセスを最適化する方法について何かアドバイスはありますか?

どうもありがとう!

以下の例では、 *choose_ecount* 変数をロックする必要があります。これをループから取り出して、ループの最後に更新するためだけにロックすることはできません。これは、内部関数によって最新の値が必要になるためです。

for(int sidx = startStep; sidx <= endStep && sidx < d.sents[lang].size(); sidx ++){
    sentence s = d.sents[lang][sidx];
    int senlen = s.words.size();
    int end_symb = s.words[senlen-1].pos;

    inside(s, lbeta);
    outside(s,lbeta, lalpha);
    long double sen_prob = lbeta[senlen-1][F][NO][0][senlen-1];

    if (lambda[0] == 0){
        mtx_.lock();
        d.sents[lang][sidx].prob = sen_prob;
        mtx_.unlock();
    }

    for(int size = 1; size <= senlen; size++)
        for(int i = 0; i <= senlen - size ; i++)
        {
            int j = i + size - 1;
            for(int k = i; k < j; k++)
            {
                int hidx = i;   int head = s.words[hidx].pos;
                for(int r = k+1; r <=j; r++)
                {
                    int aidx = r;   int arg  = s.words[aidx].pos;
                        mtx_.lock();
                    for(int kids = ONE; kids <= MAX; kids++)
                    {
                        long double num = lalpha[hidx][R][kids][i][j] * get_choose_prob(s, hidx, aidx) *
                                lbeta[hidx][R][kids - 1][i][k] * lbeta[aidx][F][NO][k+1][j];
                        long double gen_right_prob = (num / sen_prob);

                        choose_ecount[lang][head][arg] += gen_right_prob; //LOCK
                        order_ecount[lang][head][arg][RIGHT] += gen_right_prob; //LOCK
                    }
                        mtx_.unlock();
                }

}

4

3 に答える 3

1

あなたが投稿したコードから、choose_ecount と order_ecount への書き込みしか確認できません。それでは、ローカル スレッドごとのバッファーを使用して合計を計算し、最も外側のループの後にそれらを合計して、この操作のみを同期しないのはなぜでしょうか?

編集: choose_ecount の中間値にアクセスする必要がある場合、正しい中間値が存在することをどのように保証しますか? 1 つのスレッドがそのループの 2 回の反復を終了し、その間に別のスレッドで異なる結果が生成される場合があります。

代わりに、計算にバリアを使用する必要があるように思えます。

于 2013-06-28T18:02:57.697 に答える
0

内部ループでミューテックスを使用して許容できるパフォーマンスが得られる可能性は低いです。並行プログラミングは、プログラマーだけでなくコンピューターにとっても困難です。最新の CPU のパフォーマンスの大部分は、コードのブロックを外部データから独立したシーケンスとして処理できることに起因しています。シングルスレッド実行に効率的なアルゴリズムは、多くの場合、マルチスレッド実行には適していません。

ロックフリーの同期を提供できるを参照することをお勧めしますがboost::atomic、アトミック操作に必要なメモリ バリアはまだ解放されていないため、問題が発生する可能性があり、おそらくアルゴリズムを再考する必要があります。

于 2013-06-28T17:32:31.770 に答える