Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C中2个线程的执行速度比1个线程慢?_C_Multithreading_Pthreads - Fatal编程技术网

为什么C中2个线程的执行速度比1个线程慢?

为什么C中2个线程的执行速度比1个线程慢?,c,multithreading,pthreads,C,Multithreading,Pthreads,我正在使用pthread库制作一个程序,用莱布尼兹公式计算pi的精确值。我在这里工作共享资源。我的多线程函数如下所示: void*Leibniz(void*vars) { 结构变量*val=(结构变量*)变量; int STARTIMIT=val->start; int endLimit=val->end; int i; 对于(i=startLimit;i您可以使用锁来确保sum+=(pow(-1,i)/((2*i)+1));一次只在一个线程中计算。只有当多个线程同时工作时,多线程可能会更快 互

我正在使用
pthread
库制作一个程序,用莱布尼兹公式计算pi的精确值。我在这里工作共享资源。我的多线程函数如下所示:

void*Leibniz(void*vars)
{
结构变量*val=(结构变量*)变量;
int STARTIMIT=val->start;
int endLimit=val->end;
int i;

对于(i=startLimit;i您可以使用锁来确保
sum+=(pow(-1,i)/((2*i)+1));
一次只在一个线程中计算。只有当多个线程同时工作时,多线程可能会更快

互斥锁和线程创建本身代价高昂,这就是为什么多线程非并行程序比单线程程序慢的原因

你建议的解决方案是什么


没有共享资源。在这种情况下,为每个线程分别求和,然后在最后求和。分而治之。

看起来你没有表达你的想法

您可能希望在计算结束时更新总和,而不是锁定每个循环迭代(由于许多上下文切换而降低性能):

(注意:更新共享总和时只需要1个锁):

{
结构变量*val=(结构变量*)变量;
int STARTIMIT=val->start;
int endLimit=val->end;
//注:此部分按各螺纹分别计算
//这里没有(昂贵的)锁
双局部_和=0;
对于(int i=startLimit;i仅1次锁定,而不是(endLimit-startLimit+1)次锁定
pthread_mutex_lock(&mutex);
sum+=局部_和;
pthread_mutex_unlock(&mutex);
}

您不允许线程单独运行。您强制它们重复交互并通过锁相互阻止。如果您需要获取整个循环体周围的互斥锁,您将不会从线程中获得任何好处。您应该做的是为每个线程提供其自己的
sum
变量,该变量可以更新。当所有线程完成后,您可以将所有这些求和相加。也就是说,用一个求和成员展开
struct variables
。然后在加入所有线程后,将它们相加到线程生成器的末尾。如果您的程序在单线程情况下需要4.5秒,我预计您将累积如此多的项,以至于大多数项都非常小,不会对结果产生影响这是因为浮点格式的精度有限。谢谢!这大大提高了性能!但我有一个问题。如果我在文件上打印而不是添加局部变量,会怎么样?你有什么建议吗?这取决于你到底想写什么文件:最后的整和,还是部分和,计算每个线程都会导致错误?我希望每个线程对一个文件进行部分求和。由于文件I/O速度慢得多,您可能不想锁定每次写入。您可以做的是,将求和放入一个共享向量,然后将其刷新到一个文件中。谢谢。我会尝试这样做。:)谢谢!!成功!!
{
    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);
}