updated scheduling data structures

This commit is contained in:
Marcel Lütke Dreimann
2023-01-25 17:12:16 +01:00
parent c791a334df
commit 6bb6957dab
13 changed files with 179 additions and 73 deletions

View File

@@ -4,7 +4,6 @@
#include "../uos-intel-gpgpu/driver/gpgpu_driver.h"
#include "../virt/scheduler.h"
#include "../virt/strategies/rr.h"
extern gpgpu_virt::GPGPUScheduler* _global_sched;
namespace gpgpu

View File

@@ -2,7 +2,6 @@
#include "../virt/rpc.h"
#include "../virt/scheduler.h"
#include "../virt/strategies/rr.h"
#define GENODE // use genodes stdint header
#include "../uos-intel-gpgpu/driver/gpgpu_driver.h"
@@ -97,5 +96,11 @@ void Component::construct(Genode::Env& e)
Genode::log("Register RPCs...");
static gpgpu_virt::Main main(e);
#ifdef SCHED_CFS
Genode::log("Scheduler is using CFS policy!");
#else
Genode::log("Scheduler is using RR policy!");
#endif // SCHED_CFS
Genode::log("This is the UOS Intel GPGPU End!");
}

View File

@@ -7,9 +7,9 @@ LIBS = base
UOS_INTEL_GPGPU = uos-intel-gpgpu-link-cxx.o
EXT_OBJECTS = $(BUILD_BASE_DIR)/bin/$(UOS_INTEL_GPGPU)
$(TARGET): $(UOS_INTEL_GPGPU)
$(TARGET): $(UOS_INTEL_GPGPU) $(SRC_CC) ../virt/strategies/config.h
$(UOS_INTEL_GPGPU): $(SRC_CC)
$(UOS_INTEL_GPGPU):
$(MSG_BUILD) "Building uos-intel-gpgpu..."
$(MAKE) -C $(REP_DIR)/src/uos-intel-gpgpu/
cp $(REP_DIR)/src/uos-intel-gpgpu/build/$(UOS_INTEL_GPGPU) $(BUILD_BASE_DIR)/bin/.

View File

@@ -10,7 +10,6 @@
#include "../gpgpu/gpgpu_genode.h"
extern gpgpu::gpgpu_genode* _global_gpgpu_genode;
#include "scheduler.h"
#include "strategies/rr.h"
extern gpgpu_virt::GPGPUScheduler* _global_sched;
// driver
@@ -65,8 +64,15 @@ void Session_component::start_task(unsigned long kconf)
// add kernel
Kernel* kernel = new(_global_gpgpu_genode->getAlloc()) Kernel(kc);
const bool needsUpdate = vgpu.has_kernel() == false;
vgpu.add_kernel(kernel);
// trigger vgpu update
if(needsUpdate)
{
_global_sched->update_vgpu(&vgpu);
}
// trigger sched if its idle
if(_global_sched->is_idle())
{

View File

@@ -1,10 +1,17 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include "strategies/config.h"
#include "vgpu.h"
#include "kernel.h"
#include "strategies/rr.h"
#ifdef SCHED_CFS
#include "strategies/util/rbtree.h"
#include "strategies/cfs.h"
#else
#include "strategies/util/wf_queue.h"
#include "strategies/rr.h"
#endif // SCHED_CFS
// genode instance
#include "../gpgpu/gpgpu_genode.h"
@@ -103,6 +110,16 @@ namespace gpgpu_virt {
strat.removeVGPU(vgpu);
}
/**
* @brief
*
* @param vgpu
*/
void update_vgpu(VGpu* vgpu)
{
strat.updateVGPU(vgpu);
}
/**
* @brief
*
@@ -115,7 +132,11 @@ namespace gpgpu_virt {
}
};
#ifdef SCHED_CFS
using GPGPUScheduler = Scheduler<gpgpu_virt::CompletlyFair>;
#else
using GPGPUScheduler = Scheduler<gpgpu_virt::RoundRobin>;
#endif // SCHED_CFS
}
#endif // SCHEDULER_H

View File

@@ -28,6 +28,13 @@ namespace gpgpu_virt {
*/
virtual void removeVGPU(VGpu* vgpu) = 0;
/**
* @brief
*
* @param vgpu
*/
virtual void updateVGPU(VGpu* vgpu) = 0;
/**
* @brief
*

View File

@@ -22,66 +22,88 @@ static unsigned long long int rdtsc()
void CompletlyFair::addVGPU(VGpu* vgpu)
{
// create new entry
cfs_entry* ce = new (_global_gpgpu_genode->getAlloc()) cfs_entry(vgpu);
cfs_entry* ce = (cfs_entry*)vgpu;
// find current min
cfs_entry* min = nullptr;
_run_list.head([&min](cfs_entry& ce){
min = &ce;
});
_run_list.for_each([&min](cfs_entry& ce){
if(ce.runtime < min->runtime)
{
min = &ce;
}
});
cfs_entry* min = rbt_ready.getMin_cached();
// add new entry with minimum runtime
ce->runtime = min->runtime;
_run_list.enqueue(*ce);
if(min != nullptr)
{
ce->runtime = min->runtime;
}
// add vgpu to rbtree
if(vgpu->has_kernel())
{
rbt_ready.insert(*ce);
}
else
{
rbt_idle.insert(*ce);
}
}
void CompletlyFair::removeVGPU(VGpu* vgpu)
{
_run_list.for_each([&vgpu, this](cfs_entry& ce){
if(ce.vgpu == vgpu)
{
_run_list.remove(ce);
_global_gpgpu_genode->free(&ce);
}
});
if((VGpu*)_curr == vgpu || vgpu->has_kernel() )
{
rbt_ready.remove(*vgpu);
}
else
{
rbt_idle.remove(*vgpu);
}
}
void CompletlyFair::updateVGPU(VGpu* vgpu)
{
// dont touch a running vgpu! it will be updated in nextVGPU
if(vgpu == (VGpu*)_curr)
{
return;
}
rbt_idle.remove(*vgpu);
rbt_ready.insert(*vgpu);
}
VGpu* CompletlyFair::nextVGPU()
{
// update cfs entry
_curr->runtime += (rdtsc() - _curr->ts) * -_curr->vgpu->getPriority();
// list empty?
if(_run_list.empty())
return nullptr;
cfs_entry* min = nullptr;
_run_list.head([&min](cfs_entry& ce){
min = &ce;
});
_run_list.for_each([&min](cfs_entry& ce){
if(ce.runtime < min->runtime && ce.vgpu->has_kernel())
{
min = &ce;
}
});
if(min->vgpu->has_kernel()) // in case this is still the head
if(_curr != nullptr)
{
_curr = min;
_curr->ts = rdtsc();
return min->vgpu;
VGpu* curr = (VGpu*)_curr;
int prio = curr->getPriority();
_curr->runtime += (rdtsc() - _curr->ts) * -prio;
if(curr->has_kernel())
{
rbt_ready.insert(*_curr);
}
else
{
rbt_idle.insert(*_curr);
}
}
// no vgpu with kernel found
return nullptr;
VGpu* min = (VGpu*)rbt_ready.getMin_cached();
// tree empty?
if(min == nullptr)
{
_curr = nullptr;
return nullptr;
}
// remove vgpu from ready tree
rbt_ready.remove(*min);
// exec min
_curr = (cfs_entry*)min;
_curr->ts = rdtsc();
return min;
}
}

View File

@@ -1,24 +1,26 @@
#ifndef CFS_H
#define CFS_H
#include <util/fifo.h>
#include "cfs_entry.h"
#include "util/rbtree.h"
#include "../strategie.h"
namespace gpgpu_virt {
class CompletlyFair : Strategie
{
class cfs_entry : public Genode::Fifo<cfs_entry>::Element
{
public:
VGpu* vgpu;
unsigned long runtime;
unsigned long ts;
cfs_entry(VGpu* vg) : vgpu(vg), runtime(0), ts(0) {}
};
private:
Genode::Fifo<cfs_entry> _run_list; // TODO: Red Black Tree
static int compareCFSentry(const cfs_entry& a, const cfs_entry& b)
{
return (int)((long)a.runtime - (long)b.runtime);
}
static int compareAddr(const cfs_entry& a, const cfs_entry& b)
{
return (int)(&a - &b);
}
util::RBTree<cfs_entry> rbt_ready;
util::RBTree<cfs_entry> rbt_idle;
cfs_entry* _curr;
CompletlyFair(const CompletlyFair &copy) = delete;
@@ -27,7 +29,7 @@ namespace gpgpu_virt {
CompletlyFair& operator=(CompletlyFair&&) = delete;
public:
CompletlyFair() : _run_list(), _curr(nullptr) {};
CompletlyFair() : rbt_ready(compareCFSentry), rbt_idle(compareAddr), _curr(nullptr) {};
/**
* @brief
@@ -43,6 +45,13 @@ namespace gpgpu_virt {
*/
void removeVGPU(VGpu* vgpu) override;
/**
* @brief
*
* @param vgpu
*/
void updateVGPU(VGpu* vgpu) override;
/**
* @brief
*

View File

@@ -0,0 +1,17 @@
#ifndef CFS_ENTRY_H
#define CFS_ENTRY_H
#include "util/rbtree.h"
namespace gpgpu_virt {
class cfs_entry : public util::RBTree<cfs_entry>::RBNode
{
public:
unsigned long runtime;
unsigned long ts;
cfs_entry() : runtime(0), ts(0) {}
};
}
#endif // CFS_ENTRY_H

View File

@@ -0,0 +1,6 @@
#ifndef CONFIG_H
#define CONFIG_H
#define SCHED_CFS
#endif // CONFIG_H

View File

@@ -5,12 +5,12 @@ namespace gpgpu_virt
void RoundRobin::addVGPU(VGpu* vgpu)
{
_run_list.enqueue(*vgpu);
_run_list.enqueue((util::WFQueue::Chain*)vgpu);
}
void RoundRobin::removeVGPU(VGpu* vgpu)
{
_run_list.remove(*vgpu);
_run_list.remove((util::WFQueue::Chain*)vgpu);
}
VGpu* RoundRobin::nextVGPU()
@@ -24,12 +24,10 @@ VGpu* RoundRobin::nextVGPU()
for(;;)
{
// get next vgpu
_run_list.dequeue([&next](VGpu& vgpu){
next = &vgpu;
});
next = (VGpu*)_run_list.dequeue();
// add vgpu back to end of list
_run_list.enqueue(*next);
_run_list.enqueue((util::WFQueue::Chain*)next);
// check if it has kernel?
if(next->has_kernel())

View File

@@ -1,7 +1,7 @@
#ifndef RR_H
#define RR_H
#include <util/fifo.h>
#include "util/wf_queue.h"
#include "../strategie.h"
namespace gpgpu_virt {
@@ -9,7 +9,7 @@ namespace gpgpu_virt {
class RoundRobin : Strategie
{
private:
Genode::Fifo<VGpu> _run_list;
util::WFQueue _run_list;
public:
RoundRobin() : _run_list() {};
@@ -28,6 +28,13 @@ namespace gpgpu_virt {
*/
void removeVGPU(VGpu* vgpu) override;
/**
* @brief
*
* @param vgpu
*/
void updateVGPU(VGpu* vgpu) override { (void)vgpu; }; // not needed
/**
* @brief
*

View File

@@ -1,10 +1,15 @@
#ifndef VGPU_H
#define VGPU_H
#include <util/fifo.h>
#include "kernel.h"
#include <base/log.h>
#include "strategies/config.h"
#include "kernel.h"
#ifdef SCHED_CFS
#include "strategies/cfs_entry.h"
#else
#include "strategies/util/wf_queue.h"
#endif // SCHED_CFS
// driver
#define GENODE
@@ -13,7 +18,11 @@
namespace gpgpu_virt {
class VGpu : public Genode::Fifo<VGpu>::Element
#ifdef SCHED_CFS
class VGpu : public cfs_entry
#else
class VGpu : public util::WFQueue::Chain
#endif // SCHED_CFS
{
private:
// context of vgpu