runtime: fix CPU underutilization
runtime.newproc/ready are deliberately sloppy about waking new M's,
they only ensure that there is at least 1 spinning M.
Currently to compensate for that, schedule() checks if the current P
has local work and there are no spinning M's, it wakes up another one.
It does not work if goroutines do not call schedule.
With this change a spinning M wakes up another M when it finds work to do.
It's also not ideal, but it fixes the underutilization.
A proper check would require to know the exact number of runnable G's,
but it's too expensive to maintain.
Fixes issue 5586.
LGTM
"spinning" means that the M is waiting for a G, right?
If so, can we perhaps s/spinning/gwait/ in a separate CL?
spinning has a different meaning in lock implementations, and I always think of
that one.
On Fri, Jun 21, 2013 at 11:39 PM, <rsc@golang.org> wrote:
> LGTM
>
> "spinning" means that the M is waiting for a G, right?
> If so, can we perhaps s/spinning/gwait/ in a separate CL?
> spinning has a different meaning in lock implementations, and I always
> think of that one.
This is not exactly "gwait" (as it was in the old scheduler). It means
that the M itself is actively look for new work, other M's can *not*
handoff new work to this M.
This is actually very close to the "spinning" in mutex implementations:
// mutex:
try_fast_acquire(mu);
mark_as_has_spinning(mu);
for(;;) {
sleep(...);
if(try_acqurie(mu)) {
unmark_as_has_spinning(mu);
break;
}
}
// scheduler:
try_get_g_from_local_queue();
m->spinning = true;
for(...) {
if(try_to_steal_from_another_P()) {
m->spinning = false;
break;
}
}
*** Submitted as https://code.google.com/p/go/source/detail?r=1e280889f997 *** runtime: fix CPU underutilization runtime.newproc/ready are deliberately sloppy about waking ...
*** Submitted as https://code.google.com/p/go/source/detail?r=1e280889f997 ***
runtime: fix CPU underutilization
runtime.newproc/ready are deliberately sloppy about waking new M's,
they only ensure that there is at least 1 spinning M.
Currently to compensate for that, schedule() checks if the current P
has local work and there are no spinning M's, it wakes up another one.
It does not work if goroutines do not call schedule.
With this change a spinning M wakes up another M when it finds work to do.
It's also not ideal, but it fixes the underutilization.
A proper check would require to know the exact number of runnable G's,
but it's too expensive to maintain.
Fixes issue 5586.
R=rsc
CC=gobot, golang-dev
https://codereview.appspot.com/9776044
Issue 9776044: code review 9776044: runtime: fix CPU underutilization
(Closed)
Created 12 years, 1 month ago by dvyukov
Modified 11 years, 5 months ago
Reviewers:
Base URL:
Comments: 0