From 12f71c5d7e7653a65856b84a35dae70af6588a64 Mon Sep 17 00:00:00 2001 From: Robin Dietzel Date: Thu, 2 Nov 2023 22:10:09 +0100 Subject: [PATCH] FEATURE: fully support of untuned parallel algorithm --- task1/mergesort.h | 66 +++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/task1/mergesort.h b/task1/mergesort.h index d35af06..4df9f08 100644 --- a/task1/mergesort.h +++ b/task1/mergesort.h @@ -292,42 +292,50 @@ namespace algo { template static auto - merge(typename std::vector::iterator mid, std::vector &left, std::vector &right, - Comparator cmp, std::mutex &mut) { + merge(std::vector left, std::vector right, + Comparator cmp, std::mutex &mut) -> std::vector { + + std::vector output; + output.reserve(left.size() + right.size()); auto l = left.begin(); auto r = right.begin(); + auto o = output.begin(); + while (l < left.end() && r < right.end()) { if (cmp(*l, *r)) { - *mid = *l; + output.insert(o, *l); l++; } else { - *mid = *r; + output.insert(o, *r); r++; } - mid++; + o++; } while (l < left.end()) { - *mid = *l; - mid++; + output.insert(o, *l); + o++; l++; } while (r < right.end()) { - *mid = *r; - mid++; + output.insert(o, *r); + o++; r++; } - + return output; } template - static auto split(std::vector &data, std::vector &output, Comparator cmp, int depth, int &num_threads, - std::mutex &mut) { + static auto split(std::vector data, Comparator cmp, int depth, int &num_threads, + std::mutex &mut) -> std::vector{ if (data.size() <= 1) { - return; + return data; } + std::vector output; + output.reserve(data.size()); + auto mid = data.begin(); std::advance(mid, std::distance(data.begin(), data.end()) / 2); @@ -336,43 +344,29 @@ namespace algo { std::vector right(mid, data.end()); if (depth < num_threads) { - std::thread left_thread([&]() { split(left, output, cmp, depth + 1, num_threads, mut); }); - std::thread right_thread([&]() { split(right, output, cmp, depth + 1, num_threads, mut); }); + std::thread left_thread([&]() { left = split(left, cmp, depth + 1, num_threads, mut); }); + std::thread right_thread([&]() { right = split(right, cmp, depth + 1, num_threads, mut); }); left_thread.join(); right_thread.join(); } else { - split(left, output, cmp, depth + 1, num_threads, mut); - split(right, output, cmp, depth + 1, num_threads, mut); + left = split(left, cmp, depth + 1, num_threads, mut); + right = split(right, cmp, depth + 1, num_threads, mut); } - - mid = output.begin(); - std::advance(mid, std::distance(output.begin(), output.end()) / 2); - - std::vector buf; - buf.reserve(data.size()); - merge(buf.begin(), left, right, cmp, mut); - { - std::lock_guard lock(mut); - auto bufi = buf.begin(); - for(auto &element : output) { - element = *bufi; - bufi++; - } - - } + return merge(left, right, cmp, mut); } public: template static auto sort(std::vector &data, Comparator cmp, int num_threads = std::thread::hardware_concurrency()) -> void { - std::vector local_result = data; std::mutex local_result_lock; + std::vector output; + output.reserve(data.size()); - split(data, local_result, cmp, 0, num_threads, local_result_lock); - data = local_result; + output = split(data, cmp, 0, num_threads, local_result_lock); + data.assign(output.begin(), output.end()); } }; } \ No newline at end of file