2
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;
}

主线程和工作线程应该运行同样快,但结果是:

   val: 0.782206
   worker: 5017 ms
   val: 0.782206
   main: 8252 ms

主线程慢得多,我不知道为什么....


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

4

2 回答 2

1
 Main thread and the worker thread are supposed to run equally fast, but the result is:

我从未见过提供这种保证的实时操作系统之外的线程系统。在桌面系统中使用 Windows 线程和所有其他线程系统(我也使用 posix 线程,以及 MacOS X 上的轻量级线程以及 C# 线程中的线程),据我了解,在术语或速度方面没有性能保证一个线程将与另一个线程相关。

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

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

另一种选择可能是分析并查看工作的哪一部分是否需要时间。可能是操作系统调用花费的时间超过了您的工作量。

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

于 2013-06-11T15:42:07.703 回答
0

可能发生的情况是工作线程的执行与主线程的执行交错​​,因此一些工作线程的执行时间被计入主线程的时间。您可以尝试sleep(10)在工作人员的最开始放置一个(比工作人员和主要工作人员的运行时间大的时间)并再次运行。

于 2013-06-11T15:29:49.993 回答