scheduler: Keep track of core and logical CPU load

This commit is contained in:
Pawel Dziepak
2013-10-27 22:39:56 +01:00
parent 890ba7415c
commit d80cdf504f
+63 -6
View File
@@ -73,6 +73,11 @@ static int32 (*sChooseCore)(Thread* thread);
// the higher priority threads.
struct CPUEntry : public MinMaxHeapLinkImpl<CPUEntry, int32> {
int32 fCPUNumber;
bigtime_t fMeasureActiveTime;
bigtime_t fMeasureTime;
int fLoad;
};
typedef MinMaxHeap<CPUEntry, int32> CPUHeap;
static CPUEntry* sCPUEntries;
@@ -93,6 +98,8 @@ struct CoreEntry : public DoublyLinkedListLinkImpl<CoreEntry> {
int32 fCPUBoundThreads;
int32 fThreads;
int fLoad;
};
static CoreEntry* sCoreEntries;
@@ -283,13 +290,13 @@ dump_heap(CPUHeap* heap)
{
CPUHeap temp(smp_get_num_cpus());
kprintf("cpu priority actual priority\n");
kprintf("cpu priority load\n");
CPUEntry* entry = heap->PeekMinimum();
while (entry) {
int32 cpu = entry->fCPUNumber;
int32 key = CPUHeap::GetKey(entry);
kprintf("%3" B_PRId32 " %8" B_PRId32 " %15" B_PRId32 "\n", cpu, key,
get_effective_priority(gCPU[cpu].running_thread));
kprintf("%3" B_PRId32 " %8" B_PRId32 " %3d%%\n", cpu, key,
sCPUEntries[cpu].fLoad / 10);
heap->RemoveMinimum();
temp.Insert(entry, key);
@@ -311,12 +318,14 @@ static void
dump_core_thread_heap(CoreThreadHeap* heap)
{
CoreThreadHeap temp(sRunQueueCount);
int32 cpuPerCore = smp_get_num_cpus() / sRunQueueCount;
CoreEntry* entry = heap->PeekMinimum();
while (entry) {
int32 key = CoreThreadHeap::GetKey(entry);
kprintf("%4" B_PRId32 " %6" B_PRId32 " %7" B_PRId32 " %9" B_PRId32 "\n",
entry->fCoreID, key, entry->fThreads, entry->fCPUBoundThreads);
kprintf("%4" B_PRId32 " %6" B_PRId32 " %7" B_PRId32 " %9" B_PRId32
" %3d%%\n", entry->fCoreID, key, entry->fThreads,
entry->fCPUBoundThreads, entry->fLoad / cpuPerCore / 10);
heap->RemoveMinimum();
temp.Insert(entry, key);
@@ -364,7 +373,7 @@ dump_cpu_heap(int argc, char** argv)
entry = temp.PeekRoot();
}
kprintf("\ncore key threads cpu-bound\n");
kprintf("\ncore key threads cpu-bound load\n");
dump_core_thread_heap(sCoreThreadHeap);
dump_core_thread_heap(sCoreCPUBoundThreadHeap);
@@ -1264,6 +1273,45 @@ dequeue_thread(int32 thisCPU)
}
static inline void
compute_cpu_load(int32 cpu)
{
const bigtime_t kLoadMeasureInterval = 50000;
const bigtime_t kIntervalInaccuracy = kLoadMeasureInterval / 4;
int32 thisCPU = smp_get_current_cpu();
bigtime_t now = system_time();
bigtime_t deltaTime = now - sCPUEntries[cpu].fMeasureTime;
if (deltaTime < kLoadMeasureInterval)
return;
int oldLoad = sCPUEntries[cpu].fLoad;
int load = sCPUEntries[cpu].fMeasureActiveTime * 1000;
load /= max_c(now - sCPUEntries[cpu].fMeasureTime, 1);
sCPUEntries[cpu].fMeasureActiveTime = 0;
sCPUEntries[cpu].fMeasureTime = now;
deltaTime += kIntervalInaccuracy;
int n = max_c(deltaTime / kLoadMeasureInterval, 1);
if (n > 10)
sCPUEntries[cpu].fLoad = load;
else {
load *= (1 << n) - 1;
sCPUEntries[cpu].fLoad = (sCPUEntries[cpu].fLoad + load) / (1 << n);
}
if (oldLoad != load) {
int32 core = sCPUToCore[cpu];
sCoreEntries[core].fLoad -= oldLoad;
sCoreEntries[core].fLoad += sCPUEntries[cpu].fLoad;
}
}
static inline void
track_cpu_activity(Thread* oldThread, Thread* nextThread, int32 thisCore)
{
@@ -1286,9 +1334,12 @@ track_cpu_activity(Thread* oldThread, Thread* nextThread, int32 thisCore)
+ (oldThread->user_time - oldThread->cpu->last_user_time);
atomic_add64(&oldThread->cpu->active_time, active);
sCPUEntries[smp_get_current_cpu()].fMeasureActiveTime += active;
sCoreEntries[thisCore].fActiveTime += active;
}
compute_cpu_load(smp_get_current_cpu());
int32 oldPriority = get_effective_priority(oldThread);
int32 nextPriority = get_effective_priority(nextThread);
@@ -1650,6 +1701,7 @@ _scheduler_init()
sCoreEntries[i].fActiveTime = 0;
sCoreEntries[i].fThreads = 0;
sCoreEntries[i].fCPUBoundThreads = 0;
sCoreEntries[i].fLoad = 0;
status_t result = sCoreThreadHeap->Insert(&sCoreEntries[i], 0);
if (result != B_OK)
@@ -1668,6 +1720,11 @@ _scheduler_init()
for (int32 i = 0; i < cpuCount; i++) {
sCPUEntries[i].fCPUNumber = i;
sCPUEntries[i].fMeasureActiveTime = 0;
sCPUEntries[i].fMeasureTime = 0;
sCPUEntries[i].fLoad = 0;
int32 core = sCPUToCore[i];
int32 package = sCPUToPackage[i];