[英]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.