繁体   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