Why main thread is slower than worker thread in pt

2019-07-21 06:50发布

问题:

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

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

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

Main thread is much slower, I don't know why....


Problem solved. It's the compiler's problem, GCC(MinGW) behaves weirdly on Windows. I compliled the code in Visual Studio 2012, there's no speed difference.

回答1:

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

I have never seen a threading system outside a realtime OS which provided such guarantees. With windows threads and all other threading systems(I have also use posix threads, and whatever the lightweight threading on MacOS X is, and threads in C# threads) in Desktop systems it is my understanding that there are no performance guarantees in terms or how fast one thread will be in relation to another.

A possible explanation (speculation) could be that since you are using a modern quadcore it could be raising the clock rate on the main core. When there are mostly single threaded workloads modern i5/i7/AMD-FX systems raise the clock rate on one core to a pre-rated level that stock cooling can dissipate the heat for. On more parallel workloads all the cores get a smaller bump in clock speed, again pre-rated based on heat dissipation and when idle all of the cores are throttled down to minimize power usage. It is possible that the amount of background work is mostly performed on a single core and the amount of time the second thread spends on the second core is not enough to justify switching to the mode where all the cores speed is boosted.

I would try again with 4 threads and 10x the workload. If you have a tool that monitors CPU load and clock-speeds I would check that. Using that information you can infer if I am right or wrong.

Another option might be profiling and seeing if what part of the work is taking time. It could be that the OS calls are taking more time than your workload.

You could also test your software on another machine with different performance characteristics such as steady clock-speed or single core. This would provide more information.



回答2:

What could be happening is that the worker thread execution is being interleaved with main's execution, so that some of the worker thread's execution time is being counted against main's time. You could try putting a sleep(10) (some time larger than the run-time of the worker and of main) at the very beginning of the worker and run again.