簡體   English   中英

C ++多線程共享資源

[英]c++ multithreading shared resources

我正在嘗試使用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();
                }

}

從您發布的代碼中,我只能看到對choose_ecount和order_ecount的寫入。 那么,為什么不使用局部每線程緩沖區來計算總和,然后在最外層循環之后將它們加起來,僅同步此操作呢?

編輯:如果您需要訪問choose_ecount的中間值,您如何確保存在正確的中間值? 一個線程可能同時完成了其循環的2次迭代,同時在另一個線程中產生了不同的結果。

聽起來好像您需要在計算中使用障礙。

在內部循環中使用互斥鎖不太可能獲得可接受的性能。 並發編程非常困難,不僅對於程序員而言,對於計算機而言也是如此。 現代CPU的大部分性能來自能夠將代碼塊視為獨立於外部數據的序列。 對於單線程執行有效的算法通常不適合於多線程執行。

您可能想看一看boost::atomic ,它可以提供無鎖同步,但是原子操作所需的內存屏障仍然不是免費的,因此您仍然可能會遇到問題,您可能必須重新執行想想你的算法。

我猜想您將完整的問題分為從startStependStep的各個endStep以由每個線程進行處理。

由於那里有鎖定的mutex ,因此可以有效地序列化所有線程:將問題分成一些塊,這些塊按串行但未指定的順序處理。 那唯一得到的就是執行多線程的開銷。

由於您在double進行操作,因此不建議您使用原子操作:它們通常僅針對整數類型實現。

唯一可能的解決方案是遵循Kratz的建議,為每個線程復制一個choose_ecountorder_ecount ,並在線程完成后將它們縮減為一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM