← Back to context

Comment by Syzygies

9 years ago

In my experience with parallel code written in Haskell, hyper-threading offers only a very mild speedup, perhaps 10%. It is essentially an illusion, a logical convenience. (How long does it take to complete a parallel task on a dedicated machine? Four cores with hyper-threading off has nearly the performance of eight virtual cores with hyper-threading on.)

Many people have neither the interest nor the hardware access to overclock, and these processors have less overclocking headroom than earlier designs. Nevertheless, the hyper-threading hardware itself generates heat, restricting the overclocking range for given cpu cooling hardware. In this case, turning off hyper-threading pays for itself, because one can then overclock further, overtaking any advantage to hyper-threading.

It depends on what resources your code uses on-chip. If all threads are contending on the same resources, then you won't see a speedup; if they're using different resources, hyperthreading can increase throughput significantly. I've seen hyperthreading give me the equivalent of 50% of another CPU, particularly when I'm running multiple CPU-bound processes concurrently (so they're not executing the same code at the same time in some kind of parallel operation, and certainly aren't bound on synchronization primitive overheads).

  • That makes sense. I'm a mathematician, and my experience is with pure computations, homogeneous across each (virtual) core.

>It is essentially an illusion, a logical convenience.

Just checked numbers. That was my expectation as well until I came across code that experienced a bit over 80% speedup when HT was used.

It normally helps "some", and rarely hurts performance. So you might as well enable it.

  • I worry about hyperthreading hurting worst-case latency (since a thread might be assigned to run on a virtual core which does not work as fast as expected).

    • I've looked for this and I see little evidence that worries me (this on Linux). The kernel seems to schedule first on the real primaries and then on the secondaries within a pair, and the kernel is also not all that shy about moving a thread to a different CPU.