From 7082d548bc95c7aab9019de9e5864645b40bada4 Mon Sep 17 00:00:00 2001 From: robtor Date: Mon, 6 Nov 2023 21:36:10 +0100 Subject: [PATCH] complete mergesorter mt impl --- task1/main.cpp | 36 ++++++++++++++++++------------------ task1/mergesort_mt.h | 40 +++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/task1/main.cpp b/task1/main.cpp index d89a947..8493470 100644 --- a/task1/main.cpp +++ b/task1/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -60,33 +61,32 @@ auto main(int argc, char *argv[]) -> int { }, 0); auto t2 = std::chrono::high_resolution_clock::now(); - auto delay_ms = std::chrono::duration_cast(t2 - t1); - fmt::print("Sorted {} entries within {} ms in sequential\n", dataset_seq.size(), delay_ms.count()); + auto t_seq = std::chrono::duration_cast(t2 - t1); + fmt::print("Sorted {} entries within {} ms in sequential\n", dataset_seq.size(), t_seq.count()); - //const int max_depth = std::thread::hardware_concurrency(); - const int max_depth = 4; + const int threads = std::thread::hardware_concurrency(); + const int max_depth = std::log(threads); + t1 = std::chrono::high_resolution_clock::now(); - MergeSorterMT ms([](int a, int b) { + MergeSorterMT ms([](int32_t a, int32_t b) { return (a>b); - }); - std::span t = dataset_par; - int mdepth = 4; - std::recursive_mutex mut; - ms.split(t, 0, mdepth, mut); -// algo::MergeSort_mt::sort(dataset_par, [](int32_t a, int32_t b) { -// return (a > b); -// }, max_depth); + }, max_depth); + ms.sort(dataset_par); t2 = std::chrono::high_resolution_clock::now(); - delay_ms = std::chrono::duration_cast(t2 - t1); - fmt::print("Sorted {} entries within {} ms in parallel using {} threads\n", dataset_seq.size(), delay_ms.count(), max_depth); + auto t_par = std::chrono::duration_cast(t2 - t1); + fmt::print("Sorted {} entries within {} ms in parallel using {} threads and a recursion depth of {}\n", dataset_seq.size(), t_par.count(), threads, max_depth); auto eq = (dataset_seq == dataset_par); - fmt::print("Equality: {}\n", eq); - fmt::print("Parallel dataset: {}; Sequential dataset: {}\n", dataset_par.size(), dataset_seq.size()); + fmt::print("Check whether sorted arrays are equal: {}\n", (eq)? "Equal" : "not equal"); - //fmt::print("Created {} recurstions", algo::MergeSort_v1::get_recursions()); + fmt::print("------------Summary------------"); + fmt::print("t_seq = {}", t_seq.count()); + fmt::print("t_par = {}", t_par.count()); + fmt::print("speedup = {}", (1.0*t_seq/t_par)); + fmt::print("t_seq-t_par = {}", (t_seq.count() - t_par.count())); + fmt::print("-------------------------------"); std::ofstream ofile("dataset.out.dat", std::ios_base::out); if(!ofile.is_open()) { diff --git a/task1/mergesort_mt.h b/task1/mergesort_mt.h index 4853ad2..fd833fb 100644 --- a/task1/mergesort_mt.h +++ b/task1/mergesort_mt.h @@ -8,14 +8,16 @@ class MergeSorterMT { public: template - MergeSorterMT(C cmp) : cmp(cmp){ + MergeSorterMT(C cmp, int max_depth) : cmp(cmp), max_depth(max_depth) { static_assert(std::is_same, bool>(), "C must be a function that returns a bool"); } + auto sort(std::vector &data) -> void { + std::span sortable(data); + split(sortable, 0, max_depth, mut); + } - std::function cmp; - std::recursive_mutex mut; - +private: auto merge(std::span &output, std::span left, std::span right) -> void { std::vector buf; buf.reserve(left.size() + right.size()); @@ -46,39 +48,43 @@ public: } { - std::lock_guard lock(mut); + //todo: is a lock guard necessary? + //std::lock_guard lock(mut); std::move(buf.begin(), buf.end(), output.begin()); } } - auto split(std::span &data, int depth, int &max_depth, std::recursive_mutex &mut) -> void { - if(std::distance(data.begin(), data.end()) <= 1) { + auto split(std::span &data, int depth, const int &mdepth, std::recursive_mutex &mutex) -> void { + if (std::distance(data.begin(), data.end()) <= 1) { return; } auto mid = data.begin(); - std::advance(mid, std::distance(data.begin(), data.end())/2); + std::advance(mid, std::distance(data.begin(), data.end()) / 2); std::span left(data.begin(), mid); std::span right(mid, data.end()); - if(depth < max_depth) { - //std::thread left_thread(&MergeSorterMT::split, this, left, depth + 1, max_depth, mut); - //std::thread right_thread(&MergeSorterMT::split, this, right, depth + 1, max_depth, mut); - std::thread left_thread([&](){split(left, depth + 1, max_depth, mut);}); - std::thread right_thread([&](){split(right, depth + 1, max_depth, mut);}); + if (depth < mdepth) { + //todo: fix lambda call + //std::thread left_thread(&MergeSorterMT::split, this, left, depth + 1, mdepth, mutex); + //std::thread right_thread(&MergeSorterMT::split, this, right, depth + 1, mdepth, mutex); + std::thread left_thread([&]() { split(left, depth + 1, mdepth, mutex); }); + std::thread right_thread([&]() { split(right, depth + 1, mdepth, mutex); }); left_thread.join(); right_thread.join(); } else { - split(left, depth + 1, max_depth, mut); - split(right, depth + 1, max_depth, mut); + split(left, depth + 1, mdepth, mutex); + split(right, depth + 1, mdepth, mutex); } merge(data, left, right); } - - +private: + std::function cmp; + const int max_depth; + std::recursive_mutex mut; }; \ No newline at end of file