From ed68c9b11ec7b37edd112c7f97dd7ce8d2e8b876 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 3 Dec 2023 16:25:42 +0300 Subject: [PATCH] improved planner --- Planner/Planner.cpp | 2 +- Planner/Supervisor.h | 83 ++++++++++++++++++++++++++++++++++++++++++-- Planner/Task.h | 7 ++-- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/Planner/Planner.cpp b/Planner/Planner.cpp index eca4773a..0af9cbf0 100644 --- a/Planner/Planner.cpp +++ b/Planner/Planner.cpp @@ -36,6 +36,6 @@ int main(int argc, char ** argv) RunSupervisor * runSupervisor = new RunSupervisor(compilationSupervisor); printf("%ld\n", runSupervisor->getLength()); runSupervisor->print(); - runSupervisor->Do(); + runSupervisor->DoWithSchedule(maxKernels); return 0; } diff --git a/Planner/Supervisor.h b/Planner/Supervisor.h index 01043451..5183d1d1 100644 --- a/Planner/Supervisor.h +++ b/Planner/Supervisor.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include "File.h" @@ -131,20 +132,96 @@ public: void DoWithSchedule(int maxKernels) { saveState(); - map> sortedByKernelNeeds; + + // подготовка тестов + while (this->state != Execution) { + for (auto& task : this->getElements()) { + switch (this->state) { + case WorkspacesCreation: + if (task->getState() == Waiting) { + task->createWorkspace(); + task->setState(WorkspaceCreated); + } + break; + case Preparation: + if (task->getState() == WorkspaceCreated) { + task->prepareWorkspace(); + task->createLaunchScript(); + task->setState(WorkspaceReady); + } + break; + default: + //printf("id = %ld; state = %d\n", task->getId(), task->getState()); + break; + } + } + changeState(); + } + + map, std::greater> sortedByKernelNeeds; long activeTasks = 0; - for (auto& task : this->getElements()) { + for (auto& task : this->getElements()) { if (task->getState() == WorkspaceReady) { activeTasks++; sortedByKernelNeeds[task->getKernels()].push(task); } } - printf("total tasks count = %ld, active task count %ld\n", this->getLength(), activeTasks); + printf("total tasks count = %ld, active task count %ld, maxkernels %d\n", this->getLength(), activeTasks, maxKernels); + + int busyKernels = 0; + set activeTaskSet; + bool ignoreCheck = true; while (activeTasks) { + vector emptyKeys; + //ставим задачи от больших к меньшему по ядрам + for (auto& elem : sortedByKernelNeeds) { + int freeKernels = maxKernels - busyKernels; + int kernelsNeeded = elem.first; + + while (kernelsNeeded <= freeKernels && elem.second.size()) { + T* task = elem.second.front(); + elem.second.pop(); + + activeTaskSet.insert(task); + task->Start(ignoreCheck); + printf("start task with %d kernels and id %ld\n", task->getKernels(), task->getId()); + + busyKernels += task->getKernels(); + freeKernels = maxKernels - busyKernels; + } + + if (elem.second.size() == 0) + emptyKeys.push_back(kernelsNeeded); + + //если ядер не осталось, то нет смысла дальше смотреть + if (freeKernels == 0) + break; + } + + // очищаем от пустых ключей + for (auto& empty : emptyKeys) + sortedByKernelNeeds.erase(empty); + + // проверяем нет ли завершившихся задач + for (auto it = activeTaskSet.begin(); it != activeTaskSet.end(); ) + { + T* task = *(it); + + if (task->Check()) { + it++; + activeTaskSet.erase(task); + activeTasks--; + busyKernels -= task->getKernels(); + printf(" done task with %d kernels and id %ld\n", task->getKernels(), task->getId()); + + continue; + } + it++; + } } changeState(); diff --git a/Planner/Task.h b/Planner/Task.h index 2e8b3be7..95c9671f 100644 --- a/Planner/Task.h +++ b/Planner/Task.h @@ -138,7 +138,8 @@ public: } } - virtual void Check() { + //return 'true' if done, 'false' - if running + virtual bool Check() { if (Utils::Exists(workspace + "/DONE")) analyseResults(); else { @@ -156,8 +157,10 @@ public: busyKernels = Utils::min(busyKernels - kernels, maxKernels); freeKernels = Utils::max(0, maxKernels - busyKernels); //- - saveState(); //не нужно. только для отладки. анализ будет делаться архивом. + //saveState(); //не нужно. только для отладки. анализ будет делаться архивом. } + + return (state != Running); } virtual void analyseResults() {