scheduler: Fix and simplify thread migration logic in low latency mode
This patch remove the old thread migration logic which used few special cases and (broken) general check that attempted to balance threads. The new logic is pretty straightforward and seems perform well without any additional special cases. Current core is compared with the least loaded one and the thread is migrated if that would result in estimated loads of both cores (i.e. the current one and the least loaded one) to become closer to the average load (i.e. average of that two cores).
This commit is contained in:
parent
1bba129c56
commit
91810926dc
|
@ -78,13 +78,7 @@ rebalance(const ThreadData* threadData)
|
|||
SCHEDULER_ENTER_FUNCTION();
|
||||
|
||||
CoreEntry* core = threadData->Core();
|
||||
int32 coreLoad = core->GetLoad();
|
||||
int32 threadLoad = threadData->GetLoad() / core->CPUCount();
|
||||
|
||||
// If the thread produces more than 50% of the load, leave it here. In
|
||||
// such situation it is better to move other threads away.
|
||||
if (threadLoad >= coreLoad / 2)
|
||||
return core;
|
||||
ASSERT(core != NULL);
|
||||
|
||||
// Get the least loaded core.
|
||||
ReadSpinLocker coreLocker(gCoreHeapsLock);
|
||||
|
@ -94,18 +88,20 @@ rebalance(const ThreadData* threadData)
|
|||
coreLocker.Unlock();
|
||||
ASSERT(other != NULL);
|
||||
|
||||
if (other == core)
|
||||
// Check if the least loaded core is significantly less loaded than
|
||||
// the current one.
|
||||
int32 coreLoad = core->GetLoad();
|
||||
int32 otherLoad = other->GetLoad();
|
||||
if (other == core || otherLoad + kLoadDifference >= coreLoad)
|
||||
return core;
|
||||
|
||||
// If there are idle cores give them some work unless that will cause
|
||||
// the current core to become idle.
|
||||
int32 coreNewLoad = coreLoad - threadLoad;
|
||||
if (other->GetLoad() == 0 && coreNewLoad != 0)
|
||||
return other;
|
||||
// Check whether migrating the current thread would result in both core
|
||||
// loads become closer to the average.
|
||||
int32 difference = coreLoad - otherLoad - kLoadDifference;
|
||||
ASSERT(difference > 0);
|
||||
|
||||
// Attempt to keep load balanced.
|
||||
int32 otherNewLoad = other->GetLoad() + threadLoad;
|
||||
return coreNewLoad - otherNewLoad >= kLoadDifference ? other : core;
|
||||
int32 threadLoad = threadData->GetLoad() / core->CPUCount();
|
||||
return difference >= threadLoad ? other : core;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue