From ca5bcf5c5945dc298a29c59abd446e4b5505db4f Mon Sep 17 00:00:00 2001 From: Florian Schmaus <flow@cs.fau.de> Date: Tue, 22 Feb 2022 18:43:02 +0100 Subject: [PATCH] [apps]: Modernize 'fib' app --- apps/FibChildStealing.cpp | 122 ++++++++++++++++++++++++++++++++++++++ apps/Main.cpp | 90 ---------------------------- apps/fsearch/meson.build | 14 ----- apps/meson.build | 28 +++++++-- iwyu-mappings.imp | 1 + 5 files changed, 145 insertions(+), 110 deletions(-) create mode 100644 apps/FibChildStealing.cpp delete mode 100644 apps/Main.cpp diff --git a/apps/FibChildStealing.cpp b/apps/FibChildStealing.cpp new file mode 100644 index 00000000..d4aad54b --- /dev/null +++ b/apps/FibChildStealing.cpp @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright © 2020-2022 Florian Schmaus +#include <boost/program_options.hpp> +#include <cstdint> +#include <iostream> // for basic_ostream::operator<< +#include <memory> +#include <thread> + +#include "BinaryPrivateSemaphore.hpp" // for BPS +#include "CountingPrivateSemaphore.hpp" // for CPS +#include "Debug.hpp" // for DBG +#include "Fiber.hpp" // for Fiber +#include "PrivateSemaphore.hpp" // for PS +#include "Runtime.hpp" // for Runtime +#include "lib/sync/Semaphore.hpp" + +namespace po = boost::program_options; + +using fibParams = struct { + uint64_t n; + uint64_t* result; + PS* sem; +}; + +static void fib(void* voidParams) { + auto* params = static_cast<fibParams*>(voidParams); + uint64_t n = params->n; + auto* result = params->result; + PS* sem = params->sem; + + if (n < 2) { + *result = n; + } else { + CPS newSem(2); + + uint64_t a, b; + + fibParams newParams1; + newParams1.n = n - 1; + newParams1.result = &a; + newParams1.sem = &newSem; + + // Note that this is the inefficient spawn/sync variant, we + // usually would compute one previous fib number without spawning. + fibParams newParams2; + newParams2.n = n - 2; + newParams2.result = &b; + newParams2.sem = &newSem; + + Fiber* f1 = Fiber::from(&fib, &newParams1); + Fiber* f2 = Fiber::from(&fib, &newParams2); + + Runtime* runtime = Runtime::getRuntime(); + runtime->schedule(*f1); + runtime->schedule(*f2); + + DBG("fib: Calling wait for n=" << n); + newSem.wait(); + + *result = a + b; + } + + DBG("fib: Calling signalAndExit for n=" << n); + sem->signalAndExit(); +} + +// NOLINTNEXTLINE(bugprone-exception-escape) +auto main(int argc, char* argv[]) -> int { + uint64_t fibNum = -1; + po::options_description desc("Allowed options"); + // clang-format off + desc.add_options() + ("help", "Show help") + ("nthreads", po::value<unsigned int>()->default_value(std::thread::hardware_concurrency()), "Number of worker threads used by EMPER's runtime system") + ("fibnum", po::value<uint64_t>(&fibNum)->default_value(12), "The Fibonacci number to compute") + ; + // clang-format on + + // Make 'fibnum' a positional option. + po::positional_options_description pos_desc; + pos_desc.add("fibnum", -1); + + // clang-format off + auto parse_result = po::command_line_parser(argc, argv) + .options(desc) + .positional(pos_desc) + .run() + ; + // clang-format on + + po::variables_map vm; + po::store(parse_result, vm); + po::notify(vm); + + const unsigned nthreads = vm["nthreads"].as<unsigned int>(); + + std::cout << "Number of threads: " << nthreads << std::endl; + + Runtime runtime(nthreads); + + emper::lib::sync::Semaphore semaphore; + + Fiber* fibFiber = Fiber::from([&] { + uint64_t result; + BPS sem; + fibParams params = {fibNum, &result, &sem}; + + fib(¶ms); + + sem.wait(); + + std::cout << "fib(" << fibNum << ") = " << result << std::endl; + + semaphore.notify(); + }); + + runtime.scheduleFromAnywhere(*fibFiber); + + semaphore.wait(); + + return 0; +} diff --git a/apps/Main.cpp b/apps/Main.cpp deleted file mode 100644 index b2df11bd..00000000 --- a/apps/Main.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright © 2020 Florian Schmaus -#include <cstdlib> // for exit, EXIT_SUCCESS -#include <iostream> // for basic_ostream::operator<< - -#include "BinaryPrivateSemaphore.hpp" // for BPS -#include "CountingPrivateSemaphore.hpp" // for CPS -#include "Debug.hpp" // for DBG -#include "Fiber.hpp" // for Fiber -#include "PrivateSemaphore.hpp" // for PS -#include "Runtime.hpp" // for Runtime -#include "emper-common.h" // for UNUSED_ARG - -using fibParams = struct { - int n; - int* result; - PS* sem; -}; - -static void fib(void* voidParams) { - auto* params = static_cast<fibParams*>(voidParams); - int n = params->n; - int* result = params->result; - PS* sem = params->sem; - - if (n < 2) { - *result = n; - } else { - CPS newSem(2); - - int a, b; - - fibParams newParams1; - newParams1.n = n - 1; - newParams1.result = &a; - newParams1.sem = &newSem; - fibParams newParams2; - newParams2.n = n - 2; - newParams2.result = &b; - newParams2.sem = &newSem; - - Fiber* f1 = Fiber::from(&fib, &newParams1); - Fiber* f2 = Fiber::from(&fib, &newParams2); - - Runtime* runtime = Runtime::getRuntime(); - runtime->schedule(*f1); - runtime->schedule(*f2); - - DBG("fib: Calling wait for n=" << n); - newSem.wait(); - - *result = a + b; - } - - DBG("fib: Calling signalAndExit for n=" << n); - sem->signalAndExit(); -} - -static void fibKickoff() { - const int fibNum = 4; - int result; - BPS sem; - fibParams params = {fibNum, &result, &sem}; - - fib(¶ms); - - sem.wait(); - - std::cout << "fib(" << fibNum << ") = " << result << std::endl; - exit(EXIT_SUCCESS); -} - -auto main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) -> int { - // const unsigned nthreads = std::thread::hardware_concurrency(); - const unsigned nthreads = 2; - - std::cout << "Number of threads: " << nthreads << std::endl; - - Runtime runtime(nthreads); - - Fiber* fibFiber = Fiber::from(&fibKickoff); - - std::cout << "Just alloacted alpha fiber at " << fibFiber << std::endl; - - runtime.scheduleFromAnywhere(*fibFiber); - - runtime.waitUntilFinished(); - - return 0; -} diff --git a/apps/fsearch/meson.build b/apps/fsearch/meson.build index 0a55f035..80b1147d 100644 --- a/apps/fsearch/meson.build +++ b/apps/fsearch/meson.build @@ -1,17 +1,3 @@ -boost_program_options_dep = dependency('boost', modules: ['program_options']) - -boost_program_options_code = ''' -#include <boost/program_options.hpp> -int main(int argc, char* argv[]) { - boost::program_options::options_description desc("Allowed options"); -} -''' -cpp_can_link_with_boost_program_options = cpp_compiler.links( - boost_program_options_code, - name: 'boost_progam_options', - dependencies: boost_program_options_dep, -) - if cpp_has_fs_recursive_directory_iterator and cpp_can_link_with_boost_program_options fsearch_exe = executable( 'fsearch', diff --git a/apps/meson.build b/apps/meson.build index 6ee5a2d1..edc239dc 100644 --- a/apps/meson.build +++ b/apps/meson.build @@ -1,9 +1,3 @@ -fib_exe = executable( - 'fib', - 'Main.cpp', - dependencies: emper_dep, -) - worker_sleep_example_exe = executable( 'worker_sleep_example', 'WorkerSleepExample.cpp', @@ -40,4 +34,26 @@ qsort = executable( dependencies: emper_dep, ) +boost_program_options_dep = dependency('boost', modules: ['program_options']) + +boost_program_options_code = ''' +#include <boost/program_options.hpp> +int main(int argc, char* argv[]) { + boost::program_options::options_description desc("Allowed options"); +} +''' +cpp_can_link_with_boost_program_options = cpp_compiler.links( + boost_program_options_code, + name: 'boost_progam_options', + dependencies: boost_program_options_dep, +) + +if cpp_can_link_with_boost_program_options + fib_child_stealing_exe = executable( + 'fib-child-stealing', + 'FibChildStealing.cpp', + dependencies: [emper_dep, boost_program_options_dep], + ) +endif + subdir('fsearch') diff --git a/iwyu-mappings.imp b/iwyu-mappings.imp index 25cb6087..bbe2308c 100644 --- a/iwyu-mappings.imp +++ b/iwyu-mappings.imp @@ -20,6 +20,7 @@ { include: ["<boost/program_options/parsers.hpp>", "private", "<boost/program_options.hpp>", "public"], }, { include: ["<boost/program_options/positional_options.hpp>", "private", "<boost/program_options.hpp>", "public"], }, { include: ["<boost/type_index/type_index_facade.hpp>", "private", "<boost/program_options.hpp>", "public"], }, + { include: ["<boost/cstdint.hpp>", "private", "<cstdint>", "public"], }, { symbol: ["__kernel_timespec", "private", "<liburing.h>", "public" ] }, { symbol: ["std::filesystem", "private", "<filesystem>", "public" ] }, -- GitLab