簡體   English   中英

為什么C中2線程的執行比1線程慢?

[英]Why is the execution of 2 threads slower than that of 1 thread in C?

我正在使用pthread庫制作一個程序,用萊布尼茨公式找到 pi 的准確值。 我正在這里處理共享資源。 我的多線程 function 看起來像這樣:

void *Leibniz(void *vars)
{
    struct variables *val = (struct variables *)vars;
    int startLimit = val->start;
    int endLimit = val->end;
    
    int i;
    for (i = startLimit; i <= endLimit; i++)
    {
        pthread_mutex_lock(&mutex);
        sum += (pow(-1, i) / ((2 * i) + 1));
        pthread_mutex_unlock(&mutex);
    }
}

當我使用N次迭代和 1 個線程運行程序時,我在大約 4.5 秒內得到正確的 output。 當我用兩個線程運行同一個程序時,大約需要 18 秒。 我必須使用多線程來使程序更快,但恰恰相反。 誰能解釋為什么?

您使用鎖來確保sum += (pow(-1, i) / ((2 * i) + 1)); 一次只在一個線程中計算。 只有當多個線程同時工作時,多線程可能會更快。

互斥鎖和線程創建本身成本很高,這就是為什么多線程非並行程序比單線程程序慢的原因。

您提出的解決方案是什么?

沒有共享資源。 在這種情況下,每個線程都有單獨的總和,然后在最后求和。 分而治之。

看起來你沒有表達你的想法。

您可能想要的是在計算結束時更新總和,而不是鎖定每個循環迭代(由於許多上下文切換而降低了性能):

(注意:更新共享總和時只需要 1 個鎖):

{
    struct variables *val = (struct variables *)vars;
    int startLimit = val->start;
    int endLimit = val->end;

    // note: this part is calculated by each thread separatly
    // no (expensive) locking here

    double local_sum = 0;
    for (int i = startLimit; i <= endLimit; i++)
    {
         local_sum += (pow(-1, i) / ((2 * i) + 1));
    }

    // now update the sum (which is shared among all threads)
    // so need some kind of synchronization here
    // -> only 1 lock instead of (endLimit - startLimit + 1) times locking
    pthread_mutex_lock(&mutex);
    sum += local_sum;
    pthread_mutex_unlock(&mutex);
}

暫無
暫無

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

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