I've read in multiple places that Linux's default scheduler is hyperthreading aware on multi-core machines, meaning that if you have a machine with 2 real cores (4 HT), it won't schedule two busy threads onto logical cores in a way that they both run on the same physical cores (which would lead to 2x performance cost in many cases).
But when I run stress -c 2
(spawns two threads to run on 100% CPU) on my Intel i5-2520M, it often schedules (and keeps) the two threads onto HT cores 1 and 2, which map to the same physical core. Even if the system is idle otherwise.
This also happens with real programs (I'm using stress
here because it makes it easy to reproduce), and when that happens, my program understandably takes twice as long to run. Setting affinity manually with taskset
fixes that for my program, but I'd expect the a HT aware scheduler to do that correctly by itself.
You can find the HT->physical core assgnment with egrep "processor|physical id|core id" /proc/cpuinfo | sed 's/^processor/\nprocessor/g'
.
So my question is: Why does the scheduler put my threads onto the same physical core here?
Notes:
- This question is very similar to this other question, the answers to which say that Linux has quite a sophisticated thread scheduler which is HT aware. As described above, I cannot observe this fact (check for yourself with
stress -c
), and would like to know why. - I know that I can set processors affinity manually for my programs, e.g. with the
taskset
tool or with thesched_setaffinity
function. This is not what I'm looking for, I would expect the scheduler to know by itself that mapping two busy threads to a physical core and leaving one physical core completely empty is not a good idea. - I'm aware that there are some situations in which you would prefer threads to be scheduled onto the same physical core and leave the other core free, but it seems nonsensical that the scheduler would do that roughly 1/4 of the cases. It seems to me that the HT cores that it picks are completely random, or maybe those HT cores that had least activity at the time of scheduling, but that wouldn't be very hyperthreading aware, given how clearly programs with the characteristics of
stress
benefit from running on separate physical cores.
awk '/^domain/ { print $1, $2; } /^cpu/ { print $1; }' /proc/schedstat
prints, it will show CPU masks for scheduler domains. – myaut