diff --git a/emper/Fiber.hpp b/emper/Fiber.hpp index fbd63bf60933df4739473d516a2d24d58e5990ff..ed86e36f49118900166343c762957c0f49c82774 100644 --- a/emper/Fiber.hpp +++ b/emper/Fiber.hpp @@ -14,6 +14,7 @@ class Scheduler; class Dispatcher; +class LawsScheduler; class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> { public: @@ -34,6 +35,11 @@ private: Fiber* mpscNext = nullptr; + /** + * A flag used to indicate where the fiber was from. + */ + unsigned int flag = 0; + /** * Dummy constructor. Used for example by the MpscQueue. */ @@ -91,12 +97,21 @@ private: return --referenceCounter; } + inline void setFlag(unsigned int flag) { + this->flag = flag; + } + friend class adt::MpscQueue<Fiber>; friend class Scheduler; friend class Dispatcher; + friend class LawsScheduler; public: + unsigned int getFlag() { + return flag; + } + friend std::ostream& operator<<(std::ostream&, const Fiber&); static inline Fiber* from(fiber_fun_t function, void* arg) { diff --git a/emper/strategies/laws/LawsDispatcher.cpp b/emper/strategies/laws/LawsDispatcher.cpp index 32145b9ab4fc14ff1c5f6602a2db1ef68d39a7e8..5e354a35ff47d1e29e734962d880738476d22885 100644 --- a/emper/strategies/laws/LawsDispatcher.cpp +++ b/emper/strategies/laws/LawsDispatcher.cpp @@ -1,6 +1,7 @@ #include "LawsDispatcher.hpp" #include "Runtime.hpp" +#include "LawsStrategy.hpp" void LawsDispatcher::dispatchLoop() { while (true) { @@ -18,6 +19,26 @@ void LawsDispatcher::dispatchLoop() { // boolean initialize to true in order to check if this fiber // is runnable. if (isRunnable(fiber)) { +#ifdef EMPER_STATS + LawsStrategy::FiberSource fiberSource = static_cast<LawsStrategy::FiberSource>(fiber->getFlag()); + switch (fiberSource) { + case LawsStrategy::FiberSource::fromPriority: + lawsStrategy.dispatchedFiberFromPriority.fetch_add(1, std::memory_order_relaxed); + break; + case LawsStrategy::FiberSource::fromLocal: + lawsStrategy.dispatchedFiberFromLocal.fetch_add(1, std::memory_order_relaxed); + break; + case LawsStrategy::FiberSource::stolen: + lawsStrategy.dispatchedFiberStolen.fetch_add(1, std::memory_order_relaxed); + break; + case LawsStrategy::FiberSource::mainThread: + lawsStrategy.dispatchedFiberFromMainThread.fetch_add(1, std::memory_order_relaxed); + break; + default: + DIE_MSG("Unknown fiber flag: " << flag); + break; + } +#endif // The fiber was marked das runnable. Run it now. dispatch(fiber); // Update the affinity if one was set. diff --git a/emper/strategies/laws/LawsDispatcher.hpp b/emper/strategies/laws/LawsDispatcher.hpp index 2a52966f6405c8af9f7a128880dbe9ffb5ae934b..9cc63a4ecb95dd1dd7f886b08d476cc18c0952e9 100644 --- a/emper/strategies/laws/LawsDispatcher.hpp +++ b/emper/strategies/laws/LawsDispatcher.hpp @@ -2,10 +2,21 @@ #include "Dispatcher.hpp" +class LawsStrategy; + class LawsDispatcher : public Dispatcher { +private: + + LawsStrategy& lawsStrategy +#ifndef EMPER_SLEEP + ATTR_UNUSED +#endif + ; + public: - LawsDispatcher(Runtime& runtime) : Dispatcher(runtime) { + LawsDispatcher(Runtime& runtime, LawsStrategy& lawsStrategy) : Dispatcher(runtime) + , lawsStrategy(lawsStrategy) { } void dispatchLoop() override; diff --git a/emper/strategies/laws/LawsScheduler.cpp b/emper/strategies/laws/LawsScheduler.cpp index bbccdb6f2f75ca83ae1e76ad5a6c7e5c63b81525..e6a6f61b55d7c33e743c40bb7e056df754c77bb3 100644 --- a/emper/strategies/laws/LawsScheduler.cpp +++ b/emper/strategies/laws/LawsScheduler.cpp @@ -73,7 +73,8 @@ Fiber* LawsScheduler::nextFiber() { if (fiber != nullptr) { // We fetched a fiber from your local priority queue. #ifdef EMPER_STATS - lawsStrategy.nextFiberFromPriority.fetch_add(1, std::memory_order_relaxed); + int flag = static_cast<unsigned int>(LawsStrategy::FiberSource::fromPriority); + fiber->setFlag(flag); #endif return fiber; } @@ -82,7 +83,8 @@ Fiber* LawsScheduler::nextFiber() { if (likely(poped)) { #ifdef EMPER_STATS - lawsStrategy.nextFiberFromLocal.fetch_add(1, std::memory_order_relaxed); + int flag = static_cast<unsigned int>(LawsStrategy::FiberSource::fromLocal); + fiber->setFlag(flag); #endif return fiber; } @@ -98,7 +100,8 @@ Fiber* LawsScheduler::nextFiber() { poped = queues[victim]->popTop(&fiber); if (poped) { #ifdef EMPER_STATS - lawsStrategy.nextFiberStolen.fetch_add(1, std::memory_order_relaxed); + int flag = static_cast<unsigned int>(LawsStrategy::FiberSource::stolen); + fiber->setFlag(flag); #endif return fiber; } @@ -106,7 +109,13 @@ Fiber* LawsScheduler::nextFiber() { // Try the main thread queue to get work as last resort. poped = mainThreadQueue->popTop(&fiber); - if (poped) return fiber; + if (poped) { +#ifdef EMPER_STATS + int flag = static_cast<unsigned int>(LawsStrategy::FiberSource::mainThread); + fiber->setFlag(flag); +#endif + return fiber; + } return nullptr; } diff --git a/emper/strategies/laws/LawsStrategy.cpp b/emper/strategies/laws/LawsStrategy.cpp index 21476f37c61810a598a6a2968c74e62b53bb8eb0..9e8c5a6f64d8316cd970e2fcbba7adea32b8d9ae 100644 --- a/emper/strategies/laws/LawsStrategy.cpp +++ b/emper/strategies/laws/LawsStrategy.cpp @@ -8,7 +8,7 @@ Scheduler& LawsStrategy::getScheduler(Runtime& runtime) { } Dispatcher& LawsStrategy::getDispatcher(Runtime& runtime) { - Dispatcher* dispatcher = new LawsDispatcher(runtime); + Dispatcher* dispatcher = new LawsDispatcher(runtime, *this); return *dispatcher; } diff --git a/emper/strategies/laws/LawsStrategy.hpp b/emper/strategies/laws/LawsStrategy.hpp index 35cade6c6547b58feefc51164267660dbc79da2b..b703e8e07b85d101f6531ea930c734eb60c4cb6f 100644 --- a/emper/strategies/laws/LawsStrategy.hpp +++ b/emper/strategies/laws/LawsStrategy.hpp @@ -16,17 +16,26 @@ class LawsStrategy : public RuntimeStrategy { private: + enum struct FiberSource: unsigned int { + fromPriority, + fromLocal, + stolen, + mainThread, + }; + std::atomic<std::uint64_t> scheduledFibersToRemotePriority; std::atomic<std::uint64_t> scheduledFibersToLocal; - std::atomic<std::uint64_t> nextFiberFromPriority; - std::atomic<std::uint64_t> nextFiberFromLocal; - std::atomic<std::uint64_t> nextFiberStolen; + std::atomic<std::uint64_t> dispatchedFiberFromPriority; + std::atomic<std::uint64_t> dispatchedFiberFromLocal; + std::atomic<std::uint64_t> dispatchedFiberStolen; + std::atomic<std::uint64_t> dispatchedFiberFromMainThread; LawsStrategy() : scheduledFibersToRemotePriority(0) , scheduledFibersToLocal(0) - , nextFiberFromPriority(0) - , nextFiberFromLocal(0) - , nextFiberStolen(0) { + , dispatchedFiberFromPriority(0) + , dispatchedFiberFromLocal(0) + , dispatchedFiberStolen(0) + , dispatchedFiberFromMainThread(0) { } Scheduler& getScheduler(Runtime& runtime); diff --git a/emper/strategies/laws/LawsStrategyStats.cpp b/emper/strategies/laws/LawsStrategyStats.cpp index 661df43f5695d995559cbc9b1e93b99a95f66b2c..2046668fddd4b4b6b7fd69b8142bf69bd772f934 100644 --- a/emper/strategies/laws/LawsStrategyStats.cpp +++ b/emper/strategies/laws/LawsStrategyStats.cpp @@ -6,9 +6,10 @@ LawsStrategyStats::LawsStrategyStats(LawsStrategy& lawsStrategy) : scheduledFibersToRemotePriority(lawsStrategy.scheduledFibersToRemotePriority) , scheduledFibersToLocal(lawsStrategy.scheduledFibersToLocal) - , nextFiberFromPriority(lawsStrategy.nextFiberFromPriority) - , nextFiberFromLocal(lawsStrategy.nextFiberFromLocal) - , nextFiberStolen(lawsStrategy.nextFiberStolen) { + , dispatchedFiberFromPriority(lawsStrategy.dispatchedFiberFromPriority) + , dispatchedFiberFromLocal(lawsStrategy.dispatchedFiberFromLocal) + , dispatchedFiberStolen(lawsStrategy.dispatchedFiberStolen) + , dispatchedFiberFromMainThread(lawsStrategy.dispatchedFiberFromMainThread) { } uint64_t LawsStrategyStats::getScheduledFibersToRemotePriority() const { @@ -19,24 +20,29 @@ uint64_t LawsStrategyStats::getScheduledFibersToLocal() const { return scheduledFibersToLocal; } -uint64_t LawsStrategyStats::getNextFiberFromPriority() const { - return nextFiberFromPriority; +uint64_t LawsStrategyStats::getDispatchedFiberFromPriority() const { + return dispatchedFiberFromPriority; } -uint64_t LawsStrategyStats::getNextFiberFromLocal() const { - return nextFiberFromLocal; +uint64_t LawsStrategyStats::getDispatchedFiberFromLocal() const { + return dispatchedFiberFromLocal; } -uint64_t LawsStrategyStats::getNextFiberStolen() const { - return nextFiberStolen; +uint64_t LawsStrategyStats::getDispatchedFiberStolen() const { + return dispatchedFiberStolen; +} + +uint64_t LawsStrategyStats::getDispatchedFiberFromMainThread() const { + return dispatchedFiberFromMainThread; } void LawsStrategyStats::print() { std::cout << "LawsStrategyStats" << " scheduledFibersToRemotePriority:" << scheduledFibersToRemotePriority << " scheduledFibersToLocal:" << scheduledFibersToLocal - << " nextFiberFromPriority:" << nextFiberFromPriority - << " nextFiberFromLocal:" << nextFiberFromLocal - << " nextFiberStolen:" << nextFiberStolen + << " dispatchedFiberFromPriority:" << dispatchedFiberFromPriority + << " dispatchedFiberFromLocal:" << dispatchedFiberFromLocal + << " dispatchedFiberStolen:" << dispatchedFiberStolen + << " dispatchedFiberFromMainThread:" << dispatchedFiberFromMainThread << std::endl; } diff --git a/emper/strategies/laws/LawsStrategyStats.hpp b/emper/strategies/laws/LawsStrategyStats.hpp index 71347d795454315cf06f8a3fe45f60274d9a735c..6c9e82928d2478517e07b0dfdf8c0eb33901f1f8 100644 --- a/emper/strategies/laws/LawsStrategyStats.hpp +++ b/emper/strategies/laws/LawsStrategyStats.hpp @@ -11,9 +11,10 @@ class LawsStrategyStats : public RuntimeStrategyStats { private: const uint64_t scheduledFibersToRemotePriority; const uint64_t scheduledFibersToLocal; - const uint64_t nextFiberFromPriority; - const uint64_t nextFiberFromLocal; - const uint64_t nextFiberStolen; + const uint64_t dispatchedFiberFromPriority; + const uint64_t dispatchedFiberFromLocal; + const uint64_t dispatchedFiberStolen; + const uint64_t dispatchedFiberFromMainThread; public: @@ -21,9 +22,10 @@ public: uint64_t getScheduledFibersToRemotePriority() const; uint64_t getScheduledFibersToLocal() const; - uint64_t getNextFiberFromPriority() const; - uint64_t getNextFiberFromLocal() const; - uint64_t getNextFiberStolen() const; + uint64_t getDispatchedFiberFromPriority() const; + uint64_t getDispatchedFiberFromLocal() const; + uint64_t getDispatchedFiberStolen() const; + uint64_t getDispatchedFiberFromMainThread() const; virtual void print(); };