mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
Rewrote some microbenchmarks.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
#define CALLS 100
|
||||
#define CORES 4
|
||||
#define CORES 14
|
||||
#define HYPERCALL
|
||||
|
||||
//Genode::Trace::timestamp();
|
||||
@@ -26,6 +26,20 @@ static std::atomic<bool> ready{false};
|
||||
static std::atomic<bool> restart{true};
|
||||
static std::atomic<int> yield_ctr{-(31-CORES)};
|
||||
static unsigned long tsc_freq_khz = 0;
|
||||
int cores, i;
|
||||
|
||||
struct Channel {
|
||||
unsigned long yield_flag : 1,
|
||||
op : 2,
|
||||
tnum : 61;
|
||||
unsigned long delta_alloc;
|
||||
unsigned long delta_activate;
|
||||
unsigned long delta_setflag;
|
||||
unsigned long delta_findborrower;
|
||||
unsigned long delta_block;
|
||||
unsigned long delta_enter;
|
||||
unsigned long delta_return;
|
||||
};
|
||||
|
||||
struct Cell : public Genode::Thread
|
||||
{
|
||||
@@ -41,17 +55,19 @@ struct Cell : public Genode::Thread
|
||||
|
||||
void entry() override
|
||||
{
|
||||
Genode::Trace::Timestamp latency = 0;
|
||||
Nova::mword_t channel_id = 0;
|
||||
Nova::uint64_t count_allocs = 0;
|
||||
Nova::cpu_id(channel_id);
|
||||
unsigned long volatile *my_channel = &reinterpret_cast<unsigned long volatile *>(channel)[channel_id];
|
||||
struct Channel *channels = reinterpret_cast<Channel *>(channel);
|
||||
struct Channel volatile *my_channel = &channels[channel_id];
|
||||
|
||||
unsigned long _tsc_freq_ghz = tsc_freq_khz / 1000000UL;
|
||||
|
||||
Genode::log("Started worker", _id, " on CPU with affinity ", channel_id, Genode::Thread::myself()->affinity(), " signal channel: ", *my_channel, " at ", my_channel);
|
||||
//Genode::log("Started worker", _id, " on CPU with affinity ", channel_id, Genode::Thread::myself()->affinity(), " signal channel: ", my_channel->yield_flag, " at ", my_channel);
|
||||
|
||||
for (int cores = CORES; cores < 32; cores+=4) {
|
||||
for (int i = 0; i < CALLS; ) {
|
||||
for (cores = CORES; cores <= 14; cores+=4) {
|
||||
for (i = 0; i < CALLS; ) {
|
||||
|
||||
if ((i == 0 && yield_ctr >= cores-1) || (i > 0 && yield_ctr >= cores-1))
|
||||
ready = true;
|
||||
@@ -64,18 +80,26 @@ struct Cell : public Genode::Thread
|
||||
|
||||
//Genode::log("Worker ", _id, " on CPU ", channel_id, " woke up");
|
||||
counter.fetch_add(1);
|
||||
if (counter >= cores-1) {
|
||||
ready = true;
|
||||
// Genode::log("{\"allocation:\": ", allocation, ", \"id\":", _id, ",\"clk_total\":", (end-::start), ", \"mean_clk\":", (end-::start)/count_allocs ,", \"count\": ", count_allocs, "\"channel-id\":", channel_id, "},");
|
||||
}
|
||||
if (counter >= cores-1) {
|
||||
ready = true;
|
||||
// Genode::log("{\"allocation:\": ", allocation, ", \"id\":", _id, ",\"clk_total\":", (end-::start), ", \"mean_clk\":", (end-::start)/count_allocs ,", \"count\": ", count_allocs, "\"channel-id\":", channel_id, "},");
|
||||
}
|
||||
|
||||
if (my_channel->op == 2) {
|
||||
Nova::mword_t allocation = 0;
|
||||
Genode::Trace::Timestamp now = Genode::Trace::timestamp();
|
||||
Nova::core_allocation(allocation);
|
||||
my_channel->delta_return = now - my_channel->delta_return;
|
||||
Genode::log("{\"iteration\": ", i, ", \"cores\":", cores, ", \"d_block\": ", my_channel->delta_block / _tsc_freq_ghz, ", \"d_enter\":", my_channel->delta_enter / _tsc_freq_ghz, ", \"d_return\":", my_channel->delta_return / _tsc_freq_ghz, ", \"op\": \"yield\"},");
|
||||
}
|
||||
my_channel->op = 0;
|
||||
if (_id == 0) {
|
||||
//Genode::log("Waiting on start signal");
|
||||
while (ready.load() == false)
|
||||
__builtin_ia32_pause();
|
||||
|
||||
//Genode::log("Got start signal");
|
||||
_timer.msleep(20);
|
||||
_timer.msleep(2);
|
||||
|
||||
//Genode::log("Woke up for new iteration");
|
||||
ready = false;
|
||||
@@ -90,7 +114,11 @@ struct Cell : public Genode::Thread
|
||||
if (_id == 0) {
|
||||
Nova::mword_t allocated = 0;
|
||||
//Genode::log("Allocating 4 cores");
|
||||
|
||||
|
||||
my_channel->tnum = i;
|
||||
my_channel->op = 1; /* 1 for alloc, 2 for yield */
|
||||
|
||||
my_channel->delta_enter = Genode::Trace::timestamp();
|
||||
Nova::uint8_t rc = Nova::alloc_cores(cores, allocated);
|
||||
if (rc == Nova::NOVA_OK)
|
||||
{
|
||||
@@ -98,13 +126,21 @@ struct Cell : public Genode::Thread
|
||||
while(ready.load() == false)
|
||||
__builtin_ia32_pause();
|
||||
end = Genode::Trace::timestamp();
|
||||
my_channel->delta_return = end - my_channel->delta_return;
|
||||
latency += (end - ::start) / _tsc_freq_ghz;
|
||||
Nova::mword_t allocation = 0;
|
||||
Genode::log("{\"iteration\": ", i, ", \"cores\":", cores, ", \"delta_enter:\" ", my_channel->delta_enter / _tsc_freq_ghz, ", \"delta_alloc\": ", my_channel->delta_alloc / _tsc_freq_ghz, ", \"delta_activate:\": ", my_channel->delta_activate / _tsc_freq_ghz, ", \"delta_setflag\": ", my_channel->delta_setflag / _tsc_freq_ghz, ", \"delta_return\": ", my_channel->delta_return / _tsc_freq_ghz, "},");
|
||||
Nova::core_allocation(allocation);
|
||||
restart = true;
|
||||
i++;
|
||||
counter = 0;
|
||||
yield_ctr = 0;
|
||||
Genode::log("{\"cores\":", cores, "\"allocation\": ", allocation, ",\"start\": ", ::start, ", \"end\": ", end, " ,\"us\": ", (end - ::start)/_tsc_freq_ghz,"},");
|
||||
//if (i%100==0) {
|
||||
|
||||
Genode::log("{\"iteration\": ", i, ", \"cores\":", cores, ", \"allocation\": ", allocation, ",\"start\": ", ::start, ", \"end\": ", end, " ,\"ns\": ", (latency), "},");
|
||||
my_channel->delta_setflag = 0;
|
||||
latency = 0;
|
||||
//}
|
||||
i++;
|
||||
break;
|
||||
} else {
|
||||
//Genode::log("cores allocated: ", allocated);
|
||||
@@ -116,11 +152,10 @@ struct Cell : public Genode::Thread
|
||||
}
|
||||
//Genode::log("Finished allocation. Waiting for yield signal, id = ", channel_id, "\n");
|
||||
while (restart.load() == false) {
|
||||
long res = 0;
|
||||
if ((res = __atomic_load_n(my_channel, __ATOMIC_SEQ_CST)) != 0)
|
||||
{
|
||||
Genode::log("Got yield signal on channel ", channel_id, " signal: ", res, " at ", my_channel);
|
||||
Nova::yield(false);
|
||||
Channel volatile *res = __atomic_load_n(&my_channel, __ATOMIC_SEQ_CST);
|
||||
if (res->yield_flag) {
|
||||
Genode::log("Got yield signal on channel ", channel_id);
|
||||
Nova::yield(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,6 +223,7 @@ void Libc::Component::construct(Libc::Env &env)
|
||||
|
||||
pthread_t workers[space.total()];
|
||||
std::cout << "Creating workers" << std::endl;
|
||||
Genode::Trace::Timestamp thread_start = Genode::Trace::timestamp();
|
||||
for (Genode::uint16_t cpu = 1; cpu < space.total(); cpu++)
|
||||
{
|
||||
Genode::String<32> const name{"worker", cpu};
|
||||
@@ -198,6 +234,8 @@ void Libc::Component::construct(Libc::Env &env)
|
||||
// Genode::log("Created worker for CPU ", cpu);
|
||||
// worker->start();
|
||||
}
|
||||
Genode::Trace::Timestamp thread_stop = Genode::Trace::timestamp();
|
||||
Genode::log("Took ", (thread_stop - thread_start) / 2000, " μs to start workers");
|
||||
|
||||
pthread_t main_pt{};
|
||||
|
||||
@@ -209,7 +247,7 @@ void Libc::Component::construct(Libc::Env &env)
|
||||
/*Libc::pthread_create_from_thread(&main_pt, *main, &main);
|
||||
main->start();*/
|
||||
// Nova::yield(false);
|
||||
_timer.msleep(150);
|
||||
//_timer.msleep(10000);
|
||||
Libc::pthread_create_from_session(&main_pt, Cell::pthread_entry, main_cell, 8 * 4096, "main_worker", &env.cpu(), loc);
|
||||
pthread_join(main_pt, 0); });
|
||||
Genode::log("Leaving component");
|
||||
|
||||
@@ -1,20 +1,122 @@
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/log.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
|
||||
#include <suoritin/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
#include <nova/syscall-generic.h>
|
||||
#include <nova/syscalls.h>
|
||||
class Worker : public Genode::Thread {
|
||||
|
||||
public:
|
||||
Worker(Genode::Env &env)
|
||||
: Genode::Thread(env, Name("worker foo"), 4 * 4096) { }
|
||||
|
||||
void entry() override
|
||||
{
|
||||
while(true) {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Suoritin_tester
|
||||
{
|
||||
Genode::Env &_env;
|
||||
Genode::Heap _heap{_env.ram(), _env.rm()};
|
||||
|
||||
Genode::Attached_rom_dataspace _config{_env, "config"};
|
||||
|
||||
Suoritin_tester(Genode::Env &env) : _env(env)
|
||||
{
|
||||
Genode::log("Hello from Suoritin tester");
|
||||
Tukija::Suoritin::Connection suoritin {_env};
|
||||
bool greedy = false; // Shall this cell always request more resources? default: no
|
||||
//Genode::log("Hello from Suoritin tester");
|
||||
Tukija::Suoritin::Connection suoritin {_env};
|
||||
//Genode::log("Created TASKING session");
|
||||
|
||||
//Genode::log("Reading config");
|
||||
_config.update();
|
||||
|
||||
if (_config.valid()) {
|
||||
greedy = _config.xml().attribute_value("greedy", false);
|
||||
}
|
||||
|
||||
/* Create a single dummy worker */
|
||||
Worker *foo = new (_heap) Worker(_env);
|
||||
Worker *bar = new (_heap) Worker(_env);
|
||||
|
||||
//Genode::log("Querying dataspace capabilities for shared mem interface");
|
||||
Genode::Dataspace_capability workers_cap = suoritin.worker_if();
|
||||
Genode::Dataspace_capability channels_cap = suoritin.channel_if();
|
||||
Genode::Dataspace_capability evt_cap = suoritin.event_channel();
|
||||
|
||||
//Genode::log("Mapping interface into virtual address space");
|
||||
Tukija::Suoritin::Worker* workers = env.rm().attach(workers_cap);
|
||||
Tukija::Suoritin::Channel *channels = env.rm().attach(channels_cap);
|
||||
//Tukija::Suoritin::Event_channel *evtchn = env.rm().attach(evt_cap);
|
||||
|
||||
//Genode::log("Registering dummy worker named foo");
|
||||
suoritin.register_worker(Genode::Thread::Name("foo"), foo->cap());
|
||||
|
||||
//Genode::log("Creating one dummy task queue aka channel ");
|
||||
suoritin.create_channel(*workers);
|
||||
|
||||
suoritin.register_worker(Genode::Thread::Name("bar"), bar->cap());
|
||||
//Genode::log("Interfaces mapped succesfully");
|
||||
//Genode::log("Workers interface: ", workers);
|
||||
//Genode::log("Channels interface: ", channels);
|
||||
|
||||
//Genode::log("Writing dummy values");
|
||||
if (greedy)
|
||||
channels[0].length(0xDEADBEEF);
|
||||
else
|
||||
channels[0].length(0x20);
|
||||
// //Genode::log("Channel 0 has length ", channels[0].length());
|
||||
|
||||
suoritin.create_channel(workers[1]);
|
||||
channels[1].length(0xF00);
|
||||
|
||||
// Genode::log("Waiting for parent to react");
|
||||
|
||||
Genode::Trace::Timestamp rpc_delay = 0;
|
||||
|
||||
if (greedy) {
|
||||
Nova::mword_t response = 0;
|
||||
Genode::Trace::Timestamp start = Genode::Trace::timestamp();
|
||||
|
||||
for (unsigned long i = 0; i < 2000; i++) {
|
||||
channels[0].length(0xDEADBEEF);
|
||||
|
||||
// Genode::Trace::Timestamp start = Genode::Trace::timestamp();
|
||||
//Nova::hpc_read(0, 1, response);
|
||||
suoritin.request_cores();
|
||||
// Genode::Trace::Timestamp end = Genode::Trace::timestamp();
|
||||
// rpc_delay += (end - start);
|
||||
|
||||
/*while (!(__atomic_load_n(&evtchn->parent_flag, __ATOMIC_SEQ_CST)))
|
||||
__builtin_ia32_pause();
|
||||
__atomic_store_n(&evtchn->parent_flag, false, __ATOMIC_SEQ_CST);*/
|
||||
}
|
||||
Genode::Trace::Timestamp end = Genode::Trace::timestamp();
|
||||
Genode::log("{\"response\": \"", response, "\", \"delay\": ", (end-start)/4000, ", \"rpc\":", rpc_delay/4000, "},");
|
||||
}
|
||||
|
||||
//Genode::log("Exiting");
|
||||
while(true)
|
||||
;
|
||||
//_env.parent().exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
void Component::construct(Genode::Env &env) {
|
||||
static Suoritin_tester tester(env);
|
||||
try {
|
||||
static Suoritin_tester tester(env);
|
||||
} catch (Genode::Quota_guard<Genode::Cap_quota>::Limit_exceeded) {
|
||||
Genode::error("Failed: Caps exceeded.");
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,6 @@
|
||||
#include <topo_session/node.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/log.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
namespace Thread_test {
|
||||
class Tester;
|
||||
@@ -34,12 +31,12 @@ class Thread_test::Test_thread : public Thread
|
||||
{
|
||||
while(true) {
|
||||
Genode::log("Pong from thread ", _id);
|
||||
auto start = _timer.elapsed_ms();
|
||||
auto start = Genode::Trace::timestamp();
|
||||
// auto start = std::chrono::steady_clock::now ();
|
||||
_timer.msleep(_id * 1000);
|
||||
auto end = _timer.elapsed_ms();
|
||||
_timer.usleep(_id * 10);
|
||||
auto end = Genode::Trace::timestamp();
|
||||
// auto end = std::chrono::steady_clock::now();
|
||||
Genode::log("Thread ", _id, " woke up afer", (end-start), " ms.");
|
||||
Genode::log("Thread ", _id, " woke up afer", (end-start)/2000, " us.");
|
||||
Genode::log("My affinities are ", this->affinity().xpos(), "x", this->affinity().ypos(), " node: ", _env.topo().node_affinity_of(this->affinity()).id(), " native region: ", _env.topo().node_affinity_of(this->affinity()).native_id());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,20 @@ void short_loop(unsigned long k)
|
||||
}
|
||||
}
|
||||
|
||||
struct Channel {
|
||||
unsigned long yield_flag : 1,
|
||||
op : 2,
|
||||
tnum : 61;
|
||||
unsigned long delta_alloc;
|
||||
unsigned long delta_activate;
|
||||
unsigned long delta_setflag;
|
||||
unsigned long delta_findborrower;
|
||||
unsigned long delta_block;
|
||||
unsigned long delta_enter;
|
||||
unsigned long delta_return;
|
||||
};
|
||||
|
||||
|
||||
struct Hoitaja_test::Worker : public Genode::Thread
|
||||
{
|
||||
Genode::uint16_t _id;
|
||||
@@ -41,14 +55,17 @@ struct Hoitaja_test::Worker : public Genode::Thread
|
||||
{
|
||||
Nova::mword_t channel_id = 0;
|
||||
Nova::cpu_id(channel_id);
|
||||
unsigned long volatile *my_channel = &reinterpret_cast<unsigned long volatile *>(channel)[channel_id];
|
||||
//unsigned long volatile *my_channel = &reinterpret_cast<unsigned long volatile *>(channel)[channel_id];
|
||||
Channel *channels = reinterpret_cast<Channel *>(channel);
|
||||
Channel *my_channel_struct = &channels[channel_id];
|
||||
|
||||
//Genode::log("Started worker ", _id, " on CPU ", channel_id);
|
||||
Nova::yield();
|
||||
while (true) {
|
||||
while (!(__atomic_load_n(my_channel, __ATOMIC_SEQ_CST)))
|
||||
while (!(my_channel_struct->yield_flag))
|
||||
short_loop(770);
|
||||
//Genode::log("Returning core ", channel_id);
|
||||
my_channel_struct->delta_enter = Genode::Trace::timestamp();
|
||||
Nova::yield(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user