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

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.

Lei He
  • 29
  • 3
  • 1
    To make it a fairer test, first move the printfs out of the timing measurement. (Although I doubt this explains the 3-second difference you're seeing!) – Oliver Charlesworth Jun 11 '13 at 15:23
  • Also, use a common function rather than duplicating the code. And don't forget to turn on compiler optimizations (-O3). – syam Jun 11 '13 at 15:24
  • You *are* running on a multi-core processor? – Roger Rowland Jun 11 '13 at 15:25
  • @RogerRowland: Would that make a substantial difference? – Oliver Charlesworth Jun 11 '13 at 15:25
  • @OliCharlesworth maybe, maybe not, but is it worth knowing? – Roger Rowland Jun 11 '13 at 15:26
  • @RogerRowland Yes, Intel i5-2450M CPU – Lei He Jun 11 '13 at 15:27
  • @syam I turn on -03 but it makes no difference. – Lei He Jun 11 '13 at 15:31
  • Tested on my computer (Xeon X5660, Linux 3.2, GCC 4.6.3). No noticeable difference between `main`and `worker`. Edit: did not see that the question is flagged as `pthread-win32`... maybe this behavior is win32 specific. – Matthieu Rouget Jun 11 '13 at 15:33
  • On my system (Mac mini 2009, Mac OSX Mtn Lion, G++ 4.2), I also see no big difference between main and worker. main ~= worker ~= `time a.out` – Bogatyr Jun 11 '13 at 16:13
  • 1
    Windows has something called "Priority Boosts" that it can apply to threads under different circumstances. Going out on a limb here but I would guess that the main thread is getting such a boost for some reason. The docs are not clear on how boosts are applied to console applications. – Andy Brown Jun 11 '13 at 16:24

2 Answers2

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.

Sqeaky
  • 1,876
  • 3
  • 21
  • 40
  • 1
    @triple10 Be careful with the clockspeed differences between OS, windows and Linux use different mechanisms to changes clock speed. Disabling it in the BIOS/EFI would let you test my hypothesis in my answer as well. – Sqeaky Jun 11 '13 at 16:09
0

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.

Bogatyr
  • 19,255
  • 7
  • 59
  • 72
  • Whether `clock()` measures wall-clock time or individual processor time, this doesn't explain it. One thread is seeing **3 seconds** more than the other. – Oliver Charlesworth Jun 11 '13 at 15:35
  • @OliCharlesworth In what way does this not explain it? If they're interleaved then the main will include some time spent in the worker. – Bogatyr Jun 11 '13 at 15:36
  • 1
    @Oli Charlesworth Remember that in fact `clock` measures `us` not `ms` so it's three milliseconds more in the main thread, not three seconds. And I couldn't reproduce the problem on a test machine. – Mark B Jun 11 '13 at 15:38
  • _the worker thread execution is being interleaved with main's execution_: since OP has a multicore CPU (and we expect it to be free from other tasks), it should not happen in this order of magnitude. – Matthieu Rouget Jun 11 '13 at 15:39
  • @MatthieuRouget It's simple to test: save and print the actual start and stop values. Who knows about the implementation of pthreads on win32, there could be significant time in getting a thread started that doesn't happen immediately with pthread_create, and so this overhead gets attributed to main's timing. – Bogatyr Jun 11 '13 at 15:42
  • @MarkB: Ah, now that makes the difference more believable! – Oliver Charlesworth Jun 11 '13 at 15:50
  • @OliCharlesworth No, it's `ms`. – Lei He Jun 11 '13 at 15:58