mirror of
https://github.com/mmueller41/mxtasking.git
synced 2026-01-21 12:42:57 +01:00
Avoid complete restart of runtime environment.
This commit is contained in:
@@ -116,18 +116,21 @@ void Benchmark::requests_finished()
|
|||||||
{
|
{
|
||||||
const auto open_requests = --this->_open_requests;
|
const auto open_requests = --this->_open_requests;
|
||||||
|
|
||||||
|
//std::cout << "Finished request. " << this->_open_requests << " to go." << std::endl;
|
||||||
|
|
||||||
if (open_requests == 0U) // All request schedulers are done.
|
if (open_requests == 0U) // All request schedulers are done.
|
||||||
{
|
{
|
||||||
std::uint16_t core_id = mx::system::topology::core_id();
|
std::uint16_t core_id = mx::system::topology::core_id();
|
||||||
if (core_id != 0) {
|
/*if (core_id != 0) {
|
||||||
this->_open_requests++;
|
this->_open_requests++;
|
||||||
auto *stop_task = mx::tasking::runtime::new_task<StopMeasurementTask>(0U, *this);
|
auto *stop_task = mx::tasking::runtime::new_task<StopMeasurementTask>(0U, *this);
|
||||||
stop_task->annotate(static_cast<mx::tasking::TaskInterface::channel>(0));
|
stop_task->annotate(static_cast<mx::tasking::TaskInterface::channel>(0));
|
||||||
mx::tasking::runtime::spawn(*stop_task, core_id);
|
mx::tasking::runtime::spawn(*stop_task, core_id);
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
// Stop and print time (and performance counter).
|
// Stop and print time (and performance counter).
|
||||||
const auto result = this->_chronometer.stop(this->_workload.size());
|
const auto result = this->_chronometer.stop(this->_workload.size());
|
||||||
|
std::cout << "Benchmark finished." << std::endl;
|
||||||
mx::tasking::runtime::stop();
|
mx::tasking::runtime::stop();
|
||||||
std::cout << result << std::endl;
|
std::cout << result << std::endl;
|
||||||
|
|
||||||
@@ -205,6 +208,11 @@ void Benchmark::requests_finished()
|
|||||||
{
|
{
|
||||||
this->_tree.reset(nullptr);
|
this->_tree.reset(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto *restart_task = mx::tasking::runtime::new_task<RestartTask>(0U, *this);
|
||||||
|
restart_task->annotate(static_cast<mx::tasking::TaskInterface::channel>(0));
|
||||||
|
mx::tasking::runtime::spawn(*restart_task, core_id);
|
||||||
|
mx::tasking::runtime::resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <mx/util/core_set.h>
|
#include <mx/util/core_set.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace application::blinktree_benchmark {
|
namespace application::blinktree_benchmark {
|
||||||
/**
|
/**
|
||||||
@@ -116,6 +117,7 @@ class StartMeasurementTask : public mx::tasking::TaskInterface
|
|||||||
mx::tasking::TaskResult execute(const std::uint16_t, const std::uint16_t) override
|
mx::tasking::TaskResult execute(const std::uint16_t, const std::uint16_t) override
|
||||||
{
|
{
|
||||||
_benchmark._chronometer.start(static_cast<std::uint16_t>(static_cast<benchmark::phase>(_benchmark._workload)), _benchmark._current_iteration + 1, _benchmark._cores.current());
|
_benchmark._chronometer.start(static_cast<std::uint16_t>(static_cast<benchmark::phase>(_benchmark._workload)), _benchmark._current_iteration + 1, _benchmark._cores.current());
|
||||||
|
std::cout << "Started benchmark" << std::endl;
|
||||||
return mx::tasking::TaskResult::make_remove();
|
return mx::tasking::TaskResult::make_remove();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -134,4 +136,27 @@ class StopMeasurementTask : public mx::tasking::TaskInterface
|
|||||||
return mx::tasking::TaskResult::make_remove();
|
return mx::tasking::TaskResult::make_remove();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
class RestartTask : public mx::tasking::TaskInterface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Benchmark &_benchmark;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr RestartTask(Benchmark &benchmark) : _benchmark(benchmark) {}
|
||||||
|
~RestartTask() override = default;
|
||||||
|
|
||||||
|
mx::tasking::TaskResult execute(const std::uint16_t core_id, const std::uint16_t channel_id) override
|
||||||
|
{
|
||||||
|
if (_benchmark.core_set())
|
||||||
|
{
|
||||||
|
_benchmark.start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Benchmark finished." << std::endl;
|
||||||
|
mx::tasking::runtime::stop();
|
||||||
|
}
|
||||||
|
return mx::tasking::TaskResult::make_remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace application::blinktree_benchmark
|
} // namespace application::blinktree_benchmark
|
||||||
|
|||||||
@@ -125,6 +125,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void stop() noexcept { _scheduler->interrupt(); }
|
static void stop() noexcept { _scheduler->interrupt(); }
|
||||||
|
|
||||||
|
static void resume() noexcept { _scheduler->resume(); }
|
||||||
|
|
||||||
|
static const std::array<std::uint16_t,config::max_cores()> &worker_affinities() {
|
||||||
|
return _scheduler->worker_affinities();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new task.
|
* Creates a new task.
|
||||||
* @param core_id Core to allocate memory from.
|
* @param core_id Core to allocate memory from.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Scheduler::Scheduler(const mx::util::core_set &core_set, const std::uint16_t pre
|
|||||||
: _core_set(core_set), _count_channels(core_set.size()), _worker({}), _channel_numa_node_map({0U}),
|
: _core_set(core_set), _count_channels(core_set.size()), _worker({}), _channel_numa_node_map({0U}),
|
||||||
_epoch_manager(core_set.size(), resource_allocator, _is_running), _statistic(_count_channels)
|
_epoch_manager(core_set.size(), resource_allocator, _is_running), _statistic(_count_channels)
|
||||||
{
|
{
|
||||||
|
std::cout << "Creating scheduler" << std::endl;
|
||||||
this->_worker.fill(nullptr);
|
this->_worker.fill(nullptr);
|
||||||
this->_channel_numa_node_map.fill(0U);
|
this->_channel_numa_node_map.fill(0U);
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ Scheduler::Scheduler(const mx::util::core_set &core_set, const std::uint16_t pre
|
|||||||
new (memory::GlobalHeap::allocate(this->_channel_numa_node_map[worker_id], sizeof(Worker)))
|
new (memory::GlobalHeap::allocate(this->_channel_numa_node_map[worker_id], sizeof(Worker)))
|
||||||
Worker(worker_id, core_id, this->_channel_numa_node_map[worker_id], this->_is_running,
|
Worker(worker_id, core_id, this->_channel_numa_node_map[worker_id], this->_is_running,
|
||||||
prefetch_distance, this->_epoch_manager[worker_id], this->_epoch_manager.global_epoch(),
|
prefetch_distance, this->_epoch_manager[worker_id], this->_epoch_manager.global_epoch(),
|
||||||
this->_statistic);
|
this->_statistic, _cout_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <mx/util/core_set.h>
|
#include <mx/util/core_set.h>
|
||||||
#include <mx/util/random.h>
|
#include <mx/util/random.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <mx/synchronization/spinlock.h>
|
||||||
|
|
||||||
namespace mx::tasking {
|
namespace mx::tasking {
|
||||||
/**
|
/**
|
||||||
@@ -55,9 +56,18 @@ public:
|
|||||||
void interrupt() noexcept
|
void interrupt() noexcept
|
||||||
{
|
{
|
||||||
_is_running = false;
|
_is_running = false;
|
||||||
|
for (std::uint16_t worker_id = 0; worker_id < _count_channels; worker_id++) {
|
||||||
|
_worker_affinities[worker_id] = _worker[worker_id]->phys_core_id();
|
||||||
|
}
|
||||||
this->_profiler.stop();
|
this->_profiler.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const std::array<std::uint16_t,config::max_cores()> &worker_affinities() {
|
||||||
|
return _worker_affinities;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume() noexcept { _is_running = true; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Core set of this instance.
|
* @return Core set of this instance.
|
||||||
*/
|
*/
|
||||||
@@ -191,12 +201,15 @@ private:
|
|||||||
// Epoch manager for memory reclamation,
|
// Epoch manager for memory reclamation,
|
||||||
alignas(64) memory::reclamation::EpochManager _epoch_manager;
|
alignas(64) memory::reclamation::EpochManager _epoch_manager;
|
||||||
|
|
||||||
|
alignas(64) std::array<std::uint16_t,config::max_cores()> _worker_affinities{0};
|
||||||
// Profiler for task statistics.
|
// Profiler for task statistics.
|
||||||
profiling::Statistic _statistic;
|
profiling::Statistic _statistic;
|
||||||
|
|
||||||
// Profiler for idle times.
|
// Profiler for idle times.
|
||||||
profiling::Profiler _profiler{};
|
profiling::Profiler _profiler{};
|
||||||
|
|
||||||
|
synchronization::Spinlock _cout_lock{};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a decision whether a task should be scheduled to the local
|
* Make a decision whether a task should be scheduled to the local
|
||||||
* channel or a remote.
|
* channel or a remote.
|
||||||
|
|||||||
Reference in New Issue
Block a user