From e0604d1ffeb66bb52bd1b33b6b4227affe3acd43 Mon Sep 17 00:00:00 2001 From: FritzFlorian Date: Tue, 18 Feb 2020 17:10:52 +0100 Subject: [PATCH] Add unbalanced tree search benchmark for v3. --- app/benchmark_unbalanced/CMakeLists.txt | 6 +++--- app/benchmark_unbalanced/function_node.cpp | 28 ---------------------------- app/benchmark_unbalanced/main.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------- app/benchmark_unbalanced/node.h | 73 ------------------------------------------------------------------------- 4 files changed, 45 insertions(+), 165 deletions(-) delete mode 100644 app/benchmark_unbalanced/function_node.cpp delete mode 100644 app/benchmark_unbalanced/node.h diff --git a/app/benchmark_unbalanced/CMakeLists.txt b/app/benchmark_unbalanced/CMakeLists.txt index d935ada..9c86805 100644 --- a/app/benchmark_unbalanced/CMakeLists.txt +++ b/app/benchmark_unbalanced/CMakeLists.txt @@ -1,5 +1,5 @@ -add_executable(benchmark_unbalanced main.cpp node.h function_node.cpp picosha2.h) -target_link_libraries(benchmark_unbalanced pls) +add_executable(benchmark_unbalanced_pls_v3 main.cpp) +target_link_libraries(benchmark_unbalanced_pls_v3 benchmark_runner benchmark_base pls) if (EASY_PROFILER) - target_link_libraries(benchmark_unbalanced easy_profiler) + target_link_libraries(benchmark_unbalanced_pls_v3 easy_profiler) endif () diff --git a/app/benchmark_unbalanced/function_node.cpp b/app/benchmark_unbalanced/function_node.cpp deleted file mode 100644 index 1cb931e..0000000 --- a/app/benchmark_unbalanced/function_node.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "node.h" - -namespace uts { -node_state node::generate_child_state(uint32_t index) { - node_state result; - - picosha2::hash256_one_by_one hasher; - hasher.process(state_.begin(), state_.end()); - auto index_begin = reinterpret_cast(&index); - hasher.process(index_begin, index_begin + 4); - hasher.finish(); - hasher.get_hash_bytes(result.begin(), result.end()); - - return result; -} - -double node::get_state_random() { - int32_t state_random_integer; - uint32_t b = ((uint32_t) state_[16] << 24) | - ((uint32_t) state_[17] << 16) | - ((uint32_t) state_[18] << 8) | - ((uint32_t) state_[19] << 0); - b = b & 0x7fffffff; // Mask out negative values - state_random_integer = static_cast(b); - - return (double) state_random_integer / (double) INT32_MAX; -} -} diff --git a/app/benchmark_unbalanced/main.cpp b/app/benchmark_unbalanced/main.cpp index 446fe15..5e6e8b8 100644 --- a/app/benchmark_unbalanced/main.cpp +++ b/app/benchmark_unbalanced/main.cpp @@ -1,85 +1,66 @@ #include "pls/internal/scheduling/scheduler.h" -#include "pls/internal/scheduling/parallel_result.h" -#include "pls/internal/scheduling/scheduler_memory.h" -using namespace pls::internal::scheduling; +#include "pls/internal/scheduling/static_scheduler_memory.h" -#include "node.h" +using namespace pls::internal::scheduling; -const int SEED = 42; -const int ROOT_CHILDREN = 140; -const double Q = 0.124875; -const int NORMAL_CHILDREN = 8; +#include "benchmark_runner.h" +#include "benchmark_base/unbalanced.h" -const int NUM_NODES = 71069; +using namespace comparison_benchmarks::base; -parallel_result count_child_nodes(uts::node &node) { - int child_count = 1; - std::vector children = node.spawn_child_nodes(); +#include - if (children.empty()) { - return child_count; +int count_child_nodes(unbalanced::node &node) { + if (node.get_num_children() < 1) { + return 1; } - std::vector results(children.size()); - for (size_t i = 0; i < children.size(); i++) { - size_t index = i; - auto lambda = [&, index] { - results[index] = count_child_nodes(children[index]); - }; - using child_type = pls::lambda_task_by_value; - pls::scheduler::spawn_child(lambda); - } - pls::scheduler::wait_for_all(); - for (auto result : results) { - child_count += result; + std::atomic count{1}; + for (int i = 0; i < node.get_num_children(); i++) { + scheduler::spawn([i, &count, &node] { + unbalanced::node child_node = node.spawn_child_node(i); + count.fetch_add(count_child_nodes(child_node)); + }); } + scheduler::sync(); - return child_count; + return count; } -parallel_result unbalanced_tree_search(int seed, int root_children, double q, int normal_children) { - int result; - - auto lambda = [&] { - uts::node root(seed, root_children, q, normal_children); - result = count_child_nodes(root); - }; - using child_type = pls::lambda_task_by_reference; - pls::scheduler::spawn_child(lambda); - pls::scheduler::wait_for_all(); - - return result; +int unbalanced_tree_search(int seed, int root_children, double q, int normal_children) { + unbalanced::node root(seed, root_children, q, normal_children); + return count_child_nodes(root); } -constexpr size_t MAX_NUM_THREADS = 5; +constexpr int MAX_NUM_THREADS = 8; +constexpr int MAX_NUM_TASKS = 256; +constexpr int MAX_STACK_SIZE = 1024 * 2; -constexpr size_t MAX_NUM_TASKS = 128; +static_scheduler_memory global_scheduler_memory; -constexpr size_t MAX_NUM_CONTS = 128; -constexpr size_t MAX_CONT_SIZE = 512; +int main(int argc, char **argv) { + int num_threads; + string directory; + benchmark_runner::read_args(argc, argv, num_threads, directory); -volatile int result; -int main() { - PROFILE_ENABLE - static_scheduler_memory static_scheduler_memory; + string test_name = to_string(num_threads) + ".csv"; + string full_directory = directory + "/PLS_v3/"; + benchmark_runner runner{full_directory, test_name}; - scheduler scheduler{static_scheduler_memory, MAX_NUM_THREADS}; + scheduler scheduler{global_scheduler_memory, (unsigned) num_threads}; - scheduler.perform_work([&]() { - return scheduler::par([&]() { - return unbalanced_tree_search(SEED, ROOT_CHILDREN, Q, NORMAL_CHILDREN); - }, []() { - return parallel_result{0}; - }).then([](int a, int) { - result = a; - return parallel_result{0}; + runner.run_iterations(unbalanced::NUM_ITERATIONS, [&]() { + scheduler.perform_work([&]() { + unbalanced_tree_search(unbalanced::SEED, + unbalanced::ROOT_CHILDREN, + unbalanced::Q, + unbalanced::NORMAL_CHILDREN); }); - }); + }, unbalanced::WARMUP_ITERATIONS); + runner.commit_results(true); - PROFILE_SAVE("test_profile.prof") } //int main() { diff --git a/app/benchmark_unbalanced/node.h b/app/benchmark_unbalanced/node.h deleted file mode 100644 index 5111059..0000000 --- a/app/benchmark_unbalanced/node.h +++ /dev/null @@ -1,73 +0,0 @@ - -#ifndef UTS_NODE_H -#define UTS_NODE_H - -#include -#include -#include - -#include "picosha2.h" - -namespace uts { -using node_state = std::array; - -/** - * Node of an unballanced binomial tree (https://www.cs.unc.edu/~olivier/LCPC06.pdf). - * To build up the tree recursivly call spawn_child_nodes on each node until leaves are reached. - * The tree is not built up directly in memory, but rather by the recursive calls. - */ -class node { - // The state is used to allow a deterministic tree construction using sha256 hashes. - node_state state_; - - // Set this to a positive number for the root node to start the tree with a specific size - int root_children_; - - // general branching factors - double q_; - int b_; - - // Private constructor for children - node(node_state state, double q, int b) : state_{state}, root_children_{-1}, q_{q}, b_{b} {} - - std::array generate_child_state(uint32_t index); - double get_state_random(); - - public: - node(int seed, int root_children, double q, int b) : state_({{}}), root_children_{root_children}, q_{q}, b_{b} { - for (int i = 0; i < 16; i++) { - state_[i] = 0; - } - state_[16] = static_cast(0xFF & (seed >> 24)); - state_[17] = static_cast(0xFF & (seed >> 16)); - state_[18] = static_cast(0xFF & (seed >> 8)); - state_[19] = static_cast(0xFF & (seed >> 0)); - - picosha2::hash256_one_by_one hasher; - hasher.process(state_.begin(), state_.end()); - hasher.finish(); - hasher.get_hash_bytes(state_.begin(), state_.end()); - } - - std::vector spawn_child_nodes() { - double state_random = get_state_random(); - int num_children; - if (root_children_ > 0) { - num_children = root_children_; // Root always spawns children - } else if (state_random < q_) { - num_children = b_; - } else { - num_children = 0; - } - - std::vector result; - for (int i = 0; i < num_children; i++) { - result.push_back(node(generate_child_state(i), q_, b_)); - } - - return result; - } -}; -} - -#endif //UTS_NODE_H -- libgit2 0.26.0