2 ms·
I agree that the post needs to clarify the number of threads, what thread priorities were assigned, and what measures were taken to associate the threads with l
by RossBencina 7y ago
I agree that the post needs to clarify the number of threads, what thread priorities were assigned, and what measures were taken to associate the threads with logical CPUs (affinities).
I think your characterization of sched_yield() is a bit off. The man page is clear:
"sched_yield() causes the calling thread to relinquish the CPU. The thread is moved to the end of the queue for its static priority and a new thread gets to run."
and
"If the calling thread is the only thread in the highest priority list at that time, it will continue to run after a call to sched_yield()."
In particular, it does not say "I’m not actually waiting for anything visible to the scheduler and, um, run me again soon maybe?".
So assuming that the threads are running at some relatively high priority, I'm struggling to see how delays on the order of 60ms could arise.
EDIT: reading further:
"sched_yield() is intended for use with real-time scheduling policies (i.e., SCHED_FIFO or SCHED_RR). Use of sched_yield() with nondeterministic scheduling policies such as SCHED_OTHER is unspecified and very likely means your application design is broken."
So maybe that's it.
[1] http://man7.org/linux/man-pages/man2/sched_yield.2.html http://man7.org/linux/man-pages/man2/sched_yield.2.html
- zlynx 7y agoWith the current Linux scheduler, yield() means "I don't need to run and won't need to in the future either." and Linux places it at the very END of ALL SCHED_OTHER processes. Even if they are at Nice 20. So it is no surprise that latencies are high, because a yielded thread has to wait for absolutely every other thread in the system before it gets a chance to run.
- amluto 7y agoIndeed. Linux’s SCHED_OTHER doesn’t have static priorities. There was a half-baked design for locking that kind of worked 20 years ago: try to acquire the spinlock and, if it’s contended, yield. On a single CPU, that probably means that the lock holder gets to run, and if they drop the lock quickly, then the yielding thread will (on an otherwise mostly idle system) get to run soon. This was a dubious design 20 years ago, although, admittedly, OS lockout primitives were worse back then. But now, with multiple CPUs on a system, the whole scheme falls apart — the lock holder might be on a different CPU and yield() has no effect on how quickly the lock is released. So, in most cases, yield() really does mean “I don’t know what I’m doing, but I don’t want to run right now.” Anything the kernel does in response is, at best, a wild guess.