C++ 为什么在pthread-win32中主线程比工作线程慢?

C++ 为什么在pthread-win32中主线程比工作线程慢?,c++,pthreads-win32,C++,Pthreads Win32,主线程和工作线程的运行速度应该相同,但结果是: void* worker(void*) { int clk = clock(); float val = 0; for(int i = 0; i != 100000000; ++i) { val += sin(i); } printf("val: %f\n", val); printf("worker: %d ms\n", clock() - clk); return

主线程和工作线程的运行速度应该相同,但结果是:

void* worker(void*)
{
    int clk = clock();
    float val = 0;
    for(int i = 0; i != 100000000; ++i)
    {
        val += sin(i);
    }
    printf("val: %f\n", val);
    printf("worker: %d ms\n", clock() - clk);
    return 0;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, worker, NULL);
    int clk = clock();
    float val = 0;
    for(int i = 0; i != 100000000; ++i)
    {
        val += sin(i);
    }
    printf("val: %f\n", val);
    printf("main: %d ms\n", clock() - clk);
    pthread_join(tid, 0);
    return 0;
}
主线程慢得多,我不知道为什么


问题解决了。这是编译器的问题,GCC(MinGW)在Windows上的行为异常。
我在Visual Studio 2012中编写了代码,没有速度差异。

可能发生的情况是工作线程的执行与main的执行交错,因此一些工作线程的执行时间将根据main的时间计算。您可以尝试将
睡眠(10)
(比worker和main的运行时间长一些)放在worker的最开始处,然后再次运行

   val: 0.782206
   worker: 5017 ms
   val: 0.782206
   main: 8252 ms
我从未见过一个线程系统在实时操作系统之外提供这样的保证。对于桌面系统中的windows线程和所有其他线程系统(我也使用posix线程,无论MacOS X上的轻量级线程是什么,以及C#threads中的线程),我的理解是,在一个线程相对于另一个线程的速度方面没有性能保证

一个可能的解释(推测)可能是,由于您使用的是现代四核,它可能会提高主核上的时钟频率。当主要是单线程工作负载时,现代i5/i7/AMD-FX系统会将一个内核上的时钟频率提高到一个预先设定的水平,以便库存冷却可以为其散热。在更并行的工作负载上,所有内核的时钟速度都会有一个较小的波动,这也是基于散热的预额定值,并且在空闲时,所有内核都会被节流以最小化功耗。后台工作的数量可能主要在单个内核上执行,而第二个线程在第二个内核上花费的时间不足以证明切换到所有内核速度都提高的模式是合理的

我会用4个线程和10倍的工作量再试一次。如果你有一个工具,监测CPU负载和时钟速度,我会检查。利用这些信息,你可以推断我是对还是错

另一个选择可能是分析并查看工作的哪些部分需要时间。可能是操作系统调用占用的时间比您的工作负载多


您还可以在另一台具有不同性能特征的机器上测试软件,如稳定的时钟速度或单核。这将提供更多信息。

要使其成为更公平的测试,首先将printfs移出定时测量。(尽管我怀疑这是否能解释你所看到的3秒差异!)同样,使用一个公共函数,而不是复制代码。别忘了启用编译器优化(-O3)。您运行的是多核处理器?@RogerRowland:这会有实质性的区别吗?Windows有一种称为“优先级提升”的功能,它可以在不同的情况下应用于线程。在这里,我有点冒险,但我想,由于某种原因,主线得到了如此大的推动。这些文档不清楚如何将boost应用于控制台应用程序。无论
clock()
测量的是挂钟时间还是单个处理器时间,这都无法解释。一个线程比另一个线程看到的时间多3秒。@OliCharlesworth这不能用什么方式解释它?如果它们是交错的,那么主线程将包含一些在工作线程中花费的时间。@Oli Charlesworth请记住,事实上,
clock
度量的是
us
not
ms
,因此主线程中的时间多了三毫秒,而不是三秒钟。我无法在测试机器上重现这个问题。工作线程的执行与main的执行交织在一起:因为OP有一个多核CPU(我们希望它不受其他任务的影响),所以它不应该以这个数量级发生。@MatthieuRouget测试很简单:保存并打印实际的开始和停止值。谁知道pthreads在win32上的实现呢,pthread_create在启动线程时可能会花费很长时间,而这不会立即发生,因此这种开销归因于main的计时。@triple10注意操作系统之间的时钟速度差异,windows和Linux使用不同的机制来更改时钟速度。在BIOS/EFI中禁用它也可以让您在我的回答中检验我的假设。
 Main thread and the worker thread are supposed to run equally fast, but the result is: