多线程比单线程慢

我编写了一个程序,可以实时对大型数组进行大量计算。可以将任务拆分为多个子数组以进行多线程处理。但是,我无法使用线程更快地运行它。

这是为演示而创建的示例虚拟代码(相同问题)。两个线程版本最终持续 39 秒,如果它们一个接一个地计算(!),这会多几秒。数组是否是全局的等等都没有关系。我也只使用“线程构造函数”进行了一次测试,但结果相同。

我正在使用 XCode (5.1.1) 和 Macbook Air(2013 型号,Core i5,Os X 10.8.5)。是的,这是旧电脑,我很少编程...

那么,您是否可以在我的代码中发现任何逻辑错误,或者它是否在 Xcode 等设置中的某个地方?

#include <ctime>
#include <iostream>
#include <thread>

class Value
{
public:
    float a[3000000];
};

void cycle(Value *val)
{
    int i;
    for (i=0; i<3000000; i++)
        {
            val->a[i]=n;
            n+=0.0001;
        }
}

int main()
{
    Value *val1=new Value, *val2=new Value;
   
    clock_t start,stop;
   
    start=clock();
    for (int i=0; i<1000; i++)
    {
        thread first (cycle,val1);
        thread second (cycle,val2);
        first.join();
        second.join();
    }
   
    stop=clock();
    float tdiff=(((float)stop - (float)start) / 1000000.0F);
    std::cout<<endl<<"This took "<<tdiff<<" seconds...";
    return 0;
}
'''

回答

有一个笑话是这样的:

一个程序员需要1天才能完成一个程序,10个程序员需要多少天?- 10天。

代码中的工作在此循环中完成:

for (int i=0; i<1000; i++)
{
    thread first (cycle,val1);
    thread second (cycle,val2);
    first.join();
    second.join();
}

现在考虑生成和加入线程是开销。总的来说,您的并行代码所做的不仅仅是顺序代码,在一般情况下没有办法解决这个问题。并且您不是创建和加入线程一次,而是1000-times,即您添加1000-times 开销。

不要期望代码通过简单地添加更多线程来运行得更快。我向您推荐阿姆达尔定律或 古斯塔夫森定律(基本上相同,只是更积极一点)。

我建议你尝试顺序与线程,但只有一个线程来感受开销。你可以比较一下:

for (int i=0; i<1000; i++)
{
    thread first (cycle,val1);
    first.join();
}

使用不使用任何线程的顺序版本。你会惊讶于这种差异。

当线程执行大量工作(参见 Amdahl/Gustavson)并且不同线程之间没有同步时,您可以充分利用多线程。您1000加入线程的时间基本上是一个障碍,second必须等待直到first完成。最好避免这种障碍。

最后但并非最不重要的一点是,如评论中所述,您的基准测试相当有问题,因为您没有使用计算结果。也就是说,要么你没有打开优化,这使得结果变得毫无意义,要么你打开了优化,编译器可能会在你没有注意到的情况下优化一些东西。实际上,我不确定您是否正在比较执行相同工作的两个版本,或者您的并行版本是否正在执行两倍的工作。此外,在测量时间时,您需要注意测量挂钟时间而不是 cpu 时间,因为 cpu 时间增加了在多个内核上花费的时间,而您想要比较挂钟时间。

TL;DR:更多线程!= 自动减少运行时间。


以上是多线程比单线程慢的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>