Skip to content
Snippets Groups Projects
Commit 5b1c238e authored by Florian Fischer's avatar Florian Fischer
Browse files

[laws] also schedule Fibers to their priorityQueues from anywhere

First of all I think it makes sense for laws to also look at affinities of Fibers
scheduled to the AnywhereQueue.
But the actual reason is that IO completions scheduled from the completer
could be dispatched from the priorityQueue before they are found in the
expensive AnywhereQueue.

But this comes with the cost of a vcall for scheduleFromAnywhere.
parent a328256c
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@
#pragma once
#include <functional> // for function
#include <ostream>
#include "CallerEnvironment.hpp"
#include "Debug.hpp" // for LogSubsystem, LogSubsystem::SCHED, Logger
......@@ -51,14 +52,16 @@ class Scheduler : public Logger<LogSubsystem::SCHED> {
auto dequeueFiberFromAnywhereQueue() -> Fiber* { return scheduleAnywhereQueue.dequeue(); }
virtual void scheduleInternal(Fiber& fiber) = 0;
virtual void scheduleFromAnywhereInternal(Fiber& fiber) = 0;
virtual void scheduleFromAnywhereInternal(Fiber** fibers, unsigned count) = 0;
public:
void schedule(Fiber& fiber) {
LOGD("Scheduling fiber " << &fiber);
scheduleInternal(fiber);
}
// TODO: maybe this should also be a specialized function
void schedule(Fiber** fibers, unsigned count) {
for (unsigned i = 0; i < count; ++i) {
Fiber& fiber = *fibers[i];
......@@ -70,16 +73,11 @@ class Scheduler : public Logger<LogSubsystem::SCHED> {
virtual auto nextFiber() -> NextFiberResult = 0;
void scheduleFromAnywhere(Fiber& fiber) {
enqueueInAnywhereQueue(fiber);
onNewWork<CallerEnvironment::ANYWHERE>();
LOGD("Scheduling fiber " << &fiber << " from anywhere");
scheduleFromAnywhereInternal(fiber);
}
// TODO: investigate if it is still a good idea to wakeup only a single
// worker maybe we want something like onNewWork(amountOfWork)
void scheduleFromAnywhere(Fiber** fibers, unsigned count) {
insertInAnywhereQueue(fibers, count);
onNewWork<CallerEnvironment::ANYWHERE>();
scheduleFromAnywhereInternal(fibers, count);
}
};
......@@ -4,6 +4,7 @@
#include <cstdint>
#include "CallerEnvironment.hpp"
#include "Emper.hpp"
#include "LawsStrategy.hpp" // IWYU pragma: keep
#include "NextFiberResult.hpp"
......@@ -21,17 +22,17 @@ LawsScheduler::LawsScheduler(Runtime& runtime) : AbstractWorkStealingScheduler(r
addNewWorkerHook(newWorkerHook);
}
void LawsScheduler::scheduleInternal(Fiber& fiber) {
void LawsScheduler::tryScheduleToPriorityQueue(Fiber& fiber) {
workeraffinity_t* const affinity_buffer = getAffinityBuffer(fiber);
if (affinity_buffer) {
workeraffinity_t affinity = *affinity_buffer;
workerid_t workerId = Runtime::getWorkerId();
if (affinity == workerId) {
goto scheduleViaWorkStealing;
return;
}
if (affinity == Fiber::NOT_AFFINE) {
goto scheduleViaWorkStealing;
return;
}
// We found a fiber to schedule on a remote prority queue.
......@@ -40,11 +41,28 @@ void LawsScheduler::scheduleInternal(Fiber& fiber) {
emper::statsIncr(LawsStrategy::stats.scheduledFibersToPriority);
}
}
scheduleViaWorkStealing:
void LawsScheduler::scheduleInternal(Fiber& fiber) {
tryScheduleToPriorityQueue(fiber);
scheduleViaWorkStealing(fiber);
}
void LawsScheduler::scheduleFromAnywhereInternal(Fiber& fiber) {
tryScheduleToPriorityQueue(fiber);
enqueueInAnywhereQueue(fiber);
onNewWork<CallerEnvironment::ANYWHERE>();
}
void LawsScheduler::scheduleFromAnywhereInternal(Fiber** fibers, unsigned count) {
for (unsigned i = 0; i < count; ++i) {
Fiber& fiber = *fibers[i];
tryScheduleToPriorityQueue(fiber);
}
insertInAnywhereQueue(fibers, count);
onNewWork<CallerEnvironment::ANYWHERE>();
}
auto LawsScheduler::nextFiber() -> NextFiberResult {
Fiber* fiber = priorityQueue.dequeue();
if (fiber != nullptr) {
......
......@@ -17,8 +17,12 @@ class LawsScheduler : public AbstractWorkStealingScheduler {
static thread_local LawsMpscQueue priorityQueue;
void tryScheduleToPriorityQueue(Fiber& fiber);
protected:
void scheduleInternal(Fiber& fiber) override;
void scheduleFromAnywhereInternal(Fiber& fiber) override;
void scheduleFromAnywhereInternal(Fiber** fibers, unsigned count) override;
public:
LawsScheduler(Runtime& runtime);
......
......@@ -2,6 +2,7 @@
// Copyright © 2020-2021 Florian Schmaus
#pragma once
#include "CallerEnvironment.hpp"
#include "NextFiberResult.hpp"
#include "strategies/AbstractWorkStealingScheduler.hpp"
......@@ -11,6 +12,15 @@ class Runtime;
class WsScheduler : public AbstractWorkStealingScheduler {
protected:
void scheduleInternal(Fiber& fiber) override { scheduleViaWorkStealing(fiber); }
void scheduleFromAnywhereInternal(Fiber& fiber) override {
enqueueInAnywhereQueue(fiber);
onNewWork<CallerEnvironment::ANYWHERE>();
}
void scheduleFromAnywhereInternal(Fiber** fibers, unsigned count) override {
insertInAnywhereQueue(fibers, count);
onNewWork<CallerEnvironment::ANYWHERE>();
}
public:
WsScheduler(Runtime& runtime);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment