Compare commits

..

2 Commits

Author SHA1 Message Date
038ef8f439 experiments 2023-11-01 21:38:09 +01:00
11190a0eee 1 2023-11-01 21:04:12 +01:00
2 changed files with 42 additions and 32 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
project(task1) project(task1)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)

View File

@ -6,6 +6,7 @@
#include <mutex> #include <mutex>
#include <future> #include <future>
#include <ranges> #include <ranges>
#include <span>
namespace algo { namespace algo {
@ -293,8 +294,6 @@ namespace algo {
static auto static auto
merge(typename std::vector<T>::iterator mid, std::vector<T> &left, std::vector<T> &right, merge(typename std::vector<T>::iterator mid, std::vector<T> &left, std::vector<T> &right,
Comparator cmp, std::mutex &mut) { Comparator cmp, std::mutex &mut) {
{
std::lock_guard lock(mut);
auto l = left.begin(); auto l = left.begin();
auto r = right.begin(); auto r = right.begin();
@ -319,11 +318,12 @@ namespace algo {
mid++; mid++;
r++; r++;
} }
}
} }
template<typename T, typename Comparator> template<typename T, typename Comparator>
static auto split(std::vector<T> &data, std::vector<T> &outdata, Comparator cmp, int depth, int &num_threads, std::mutex &mut) { static auto split(std::vector<T> &data, std::vector<T> &output, Comparator cmp, int depth, int &num_threads,
std::mutex &mut) {
if (data.size() <= 1) { if (data.size() <= 1) {
return; return;
} }
@ -332,26 +332,36 @@ namespace algo {
std::advance(mid, std::distance(data.begin(), data.end()) / 2); std::advance(mid, std::distance(data.begin(), data.end()) / 2);
std::vector<T> left(data.begin(), mid);
std::vector<T> right(mid, data.end());
std::vector<T> left(std::make_move_iterator(data.begin()), std::make_move_iterator(mid));
std::vector<T> right(std::make_move_iterator(mid), std::make_move_iterator(data.end()));
if (depth < num_threads) { if (depth < num_threads) {
std::thread left_thread([&]() { split(left, outdata, cmp, depth + 1, num_threads, mut); }); std::thread left_thread([&]() { split(left, output, cmp, depth + 1, num_threads, mut); });
std::thread right_thread([&]() { split(right, outdata, cmp, depth + 1, num_threads, mut); }); std::thread right_thread([&]() { split(right, output, cmp, depth + 1, num_threads, mut); });
left_thread.join(); left_thread.join();
right_thread.join(); right_thread.join();
} else { } else {
split(left, outdata, cmp, depth + 1, num_threads, mut); split(left, output, cmp, depth + 1, num_threads, mut);
split(right, outdata, cmp, depth + 1, num_threads, mut); split(right, output, cmp, depth + 1, num_threads, mut);
} }
mid = outdata.begin(); mid = output.begin();
std::advance(mid, std::distance(outdata.begin(), outdata.end())/2); std::advance(mid, std::distance(output.begin(), output.end()) / 2);
merge(mid, left, right, cmp, mut);
std::vector<T> 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++;
}
}
} }
public: public: