diff --git a/repos/mml/run/portal_experiment.run b/repos/mml/run/portal_experiment.run new file mode 100644 index 0000000000..f79b9a81c6 --- /dev/null +++ b/repos/mml/run/portal_experiment.run @@ -0,0 +1,141 @@ +set build_components { + core init hoitaja timer app/portal_experiment app/volatile_cell +} + +source ${genode_dir}/repos/base/run/platform_drv.inc +append_platform_drv_build_components +build $build_components +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2022-07-20 14:30 + + + + + + + + + + + + + + + + + + + + + +} +set boot_modules { + core init hoitaja timer vfs.lib.so libm.lib.so libc.lib.so stdcxx.lib.so ld.lib.so portal_experiment volatile_cell +} +build_boot_image $boot_modules +append qemu_args "-nographic" +run_genode_until forever diff --git a/repos/mml/src/app/loopbench/target.mk b/repos/mml/src/app/loopbench/target.mk new file mode 100644 index 0000000000..26cfb9356a --- /dev/null +++ b/repos/mml/src/app/loopbench/target.mk @@ -0,0 +1,10 @@ +TARGET = loopbench +SRC_CC = loop_bench_mxtasking.cpp \ + loop.c \ + bench.c \ + profiling.c + +LIBS += base libc stdcxx mxtasking +CC_OPT += -Wno-error -fno-aligned-new -g +CC_OLEVEL = -O0 +CC_CXX_WARN_STRICT = diff --git a/repos/mml/src/app/portal_experiment/main.cc b/repos/mml/src/app/portal_experiment/main.cc new file mode 100644 index 0000000000..8374a46815 --- /dev/null +++ b/repos/mml/src/app/portal_experiment/main.cc @@ -0,0 +1,216 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CALLS 100 +#define CORES 4 +#define HYPERCALL + + //Genode::Trace::timestamp(); +static Genode::Trace::Timestamp rdtsc_cost = 0; +Genode::Env *genv = nullptr; +static Genode::Trace::Timestamp start = 0; +static const unsigned long loops = 10000UL; +static Nova::mword_t channel = 0; +static std::atomic counter(0); +static std::atomic ready{false}; +static std::atomic restart{true}; +static std::atomic yield_ctr{-(31-CORES)}; +static unsigned long tsc_freq_khz = 0; + +struct Cell : public Genode::Thread +{ + Genode::uint16_t _id; + Libc::Env &env; + Timer::Connection &_timer; + + static void *pthread_entry(void *args) { + Cell *cell = reinterpret_cast(args); + cell->entry(); + return nullptr; + } + + void entry() override + { + Nova::mword_t channel_id = 0; + Nova::uint64_t count_allocs = 0; + Nova::cpu_id(channel_id); + unsigned long volatile *my_channel = &reinterpret_cast(channel)[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); + + for (int cores = CORES; cores < 32; cores+=4) { + for (int i = 0; i < CALLS; ) { + + if ((i == 0 && yield_ctr >= cores-1) || (i > 0 && yield_ctr >= cores-1)) + ready = true; + + if (_id != 0 && restart.load()) { + yield_ctr.fetch_add(1); + // Genode::log("Worker ", _id, "yielded, yield_ctr = ", yield_ctr.load()); + Nova::yield(); + } + + //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 (_id == 0) { + //Genode::log("Waiting on start signal"); + while (ready.load() == false) + __builtin_ia32_pause(); + + //Genode::log("Got start signal"); + _timer.msleep(20); + + //Genode::log("Woke up for new iteration"); + ready = false; + restart = false; + ::start = Genode::Trace::timestamp(); + } + + Genode::Trace::Timestamp end = 0; + while (_id==0) + { + + if (_id == 0) { + Nova::mword_t allocated = 0; + //Genode::log("Allocating 4 cores"); + + Nova::uint8_t rc = Nova::alloc_cores(cores, allocated); + if (rc == Nova::NOVA_OK) + { + + while(ready.load() == false) + __builtin_ia32_pause(); + end = Genode::Trace::timestamp(); + Nova::mword_t allocation = 0; + 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,"},"); + break; + } else { + //Genode::log("cores allocated: ", allocated); + break; + // Genode::log("cores allocated: ", allocated); + } + count_allocs++; + } + } + //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); + } + } + } + } + Genode::log("Benchmak finished."); + } + Cell(Libc::Env &env, Timer::Connection &timer, Genode::uint16_t id, Location const &location) + : Thread(env, Name("test_", location.xpos(), "x", location.ypos()), 4 * 4096, location, Weight(), env.cpu()), _id(id), env(env), _timer(timer) + { } +}; + + +void Libc::Component::construct(Libc::Env &env) +{ + Nova::uint8_t res = 0; + genv = &env; + + Libc::with_libc([&]() + { + Timer::Connection _timer{env}; + + Genode::Ram_dataspace_capability ds = env.ram().alloc(4096); + channel = env.rm().attach(ds); + + Genode::memset(reinterpret_cast(channel), 0, 4096); + + //Genode::Heap _heap{env.ram(), env.rm()}; + + //Genode::log("Registering MxTasking entrypoint"); + if ((res = Nova::mxinit(0, 0, channel))) { + Genode::error("Failed to init MxTasking: ", res); + } + Genode::log("Registered MxTasking, yielding ..."); + + try { + Genode::Attached_rom_dataspace info(env, "platform_info"); + tsc_freq_khz = info.xml().sub_node("hardware").sub_node("tsc") + .attribute_value("freq_khz", 0ULL); + } catch (...) { }; + + start = Genode::Trace::timestamp(); + for (unsigned c = 0; c < 1000; c++) { + //Genode::Trace::Timestamp start = Genode::Trace::timestamp(); + + /*Nova::uint8_t rc = Nova::yield(); + if (rc != Nova::NOVA_OK) + break;*/ + Genode::Trace::timestamp(); + // Genode::Trace::Timestamp end = Genode::Trace::timestamp(); + // delay += (end - start); + } + Genode::Trace::Timestamp end = Genode::Trace::timestamp(); + rdtsc_cost = (end - start) / 1000 / 2; + + Genode::log("My affinity is ", env.cpu().affinity_space(), " of size ", env.cpu().affinity_space().total()); + Genode::log("Will create workers for affinity space: ", env.topo().global_affinity_space()); + start = Genode::Trace::timestamp(); + Genode::Thread *me = Genode::Thread::myself(); + + unsigned long cpuid = 0; + Nova::cpu_id(cpuid); + + Genode::Affinity::Space space = env.topo().global_affinity_space(); + Genode::log("My main thread is on phys. CPU ", cpuid); + + pthread_t workers[space.total()]; + std::cout << "Creating workers" << std::endl; + for (Genode::uint16_t cpu = 1; cpu < space.total(); cpu++) + { + Genode::String<32> const name{"worker", cpu}; + if (cpu == (space.total() - cpuid)) + continue; + Cell *worker = new Cell(env, _timer, cpu, space.location_of_index(cpu)); + Libc::pthread_create_from_session(&workers[cpu], Cell::pthread_entry, worker, 4 * 4096, name.string(), &env.cpu(), space.location_of_index(cpu)); + // Genode::log("Created worker for CPU ", cpu); + // worker->start(); + } + + pthread_t main_pt{}; + + Genode::Affinity::Location loc = me->affinity(); + //Genode::log("Starting main worker on CPU ", cpuid); + Cell *main_cell = new Cell(env, _timer, 0, loc); + + //Cell *main = new (_heap) Cell(env, 0, Genode::Affinity::Location(20,0)); + /*Libc::pthread_create_from_thread(&main_pt, *main, &main); + main->start();*/ + // Nova::yield(false); + _timer.msleep(150); + 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"); +} \ No newline at end of file diff --git a/repos/mml/src/app/portal_experiment/target.mk b/repos/mml/src/app/portal_experiment/target.mk new file mode 100644 index 0000000000..ec8ed005cc --- /dev/null +++ b/repos/mml/src/app/portal_experiment/target.mk @@ -0,0 +1,8 @@ +TARGET = portal_experiment +SRC_CC = main.cc +LIBS = base libc stdcxx +INC_DIR += $(call select_from_repositories,src/lib/libc) +INC_DIR += $(call select_from_repositories,src/lib/libc)/spec/x86_64 +ifdef HYPERCALL +CC_OPT += -DHYPERCALL +endif \ No newline at end of file