MT impl WIP

This commit is contained in:
Robin Dietzel 2023-11-01 12:32:52 +01:00
parent c560bfe4cc
commit bbf0c0346f
2 changed files with 12 additions and 10 deletions

View File

@ -62,14 +62,16 @@ auto main(int argc, char *argv[]) -> int {
auto delay_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
fmt::print("Sorted {} entries within {} ms in sequential\n", dataset_seq.size(), delay_ms.count());
static constexpr int nthreads = 16;
t1 = std::chrono::high_resolution_clock::now();
algo::MergeSort_v2::sort(dataset_par.begin(), dataset_par.end(), [](int32_t a, int32_t b) {
return (a > b);
}, 16);
}, nthreads);
t2 = std::chrono::high_resolution_clock::now();
delay_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
fmt::print("Sorted {} entries within {} ms in parallel using {} threads\n", dataset_seq.size(), delay_ms.count(), 16);
fmt::print("Sorted {} entries within {} ms in parallel using {} threads\n", dataset_seq.size(), delay_ms.count(), nthreads);
auto eq = (dataset_seq == dataset_par);
fmt::print("Equality: {}\n", eq);

View File

@ -83,10 +83,9 @@ namespace algo {
class MergeSort_v2 {
private:
//Caution: non thread-safe, must be executed with additional protection (e.g. lock_guard)
template<typename Iterator, typename Comparator>
static auto
merge(Iterator start, Iterator middle, Iterator end, Comparator cmp, Iterator output_start) -> void {
merge(Iterator start, Iterator middle, Iterator end, Comparator cmp, Iterator output_start, std::recursive_mutex &dataset_guard) -> void {
Iterator start_m = start;
Iterator begin = output_start;
Iterator start2 = middle + 1;
@ -116,20 +115,23 @@ namespace algo {
output_start++;
}
dataset_guard.lock();
const auto size = std::distance(start_m, end);
for (auto i = 0; i <= size; i++, start_m++, begin++) {
*start_m = *begin;
}
dataset_guard.unlock();
}
template<typename Container, typename Iterator, typename Comparator>
static auto ms_split(Container &output_vec, Iterator start, Iterator end, Comparator cmp, Iterator output_start,
int &nthreads, std::mutex &dataset_guard, std::mutex &depth_guard) -> void {
int &nthreads, std::recursive_mutex &dataset_guard, std::mutex &depth_guard) -> void {
Iterator mid = start;
Iterator begin = output_start;
if (std::distance(start, end) < 1) {
//Quit on smalles list size (one element is always sorted)
return;
} else {
if (nthreads > 1) {
@ -151,8 +153,7 @@ namespace algo {
//merge everything together starting from the complete beginning
t1.join();
t2.join();
const std::lock_guard<std::mutex> lock(dataset_guard);
merge(start, mid, end, cmp, begin);
merge(start, mid, end, cmp, begin, dataset_guard);
} else {
//move mid iterator litterally to the mid
std::advance(mid, std::distance(start, end) / 2);
@ -165,8 +166,7 @@ namespace algo {
ms_split(output_vec, mid + 1, end, cmp, output_start, nthreads, dataset_guard, depth_guard);
//merge everything together starting from the complete beginning
const std::lock_guard<std::mutex> lock(dataset_guard);
merge(start, mid, end, cmp, begin);
merge(start, mid, end, cmp, begin, dataset_guard);
}
}
}
@ -176,7 +176,7 @@ namespace algo {
static auto sort(Iterator start, Iterator end, Comparator cmp, int nthreads) -> void {
using valtype = typename std::iterator_traits<Iterator>::value_type;
std::vector<valtype> temporary_dataset(std::distance(start, end));
std::mutex dataset_guard;
std::recursive_mutex dataset_guard;
std::mutex depth_guard;
ms_split(temporary_dataset, start, end - 1, cmp, temporary_dataset.begin(), nthreads, dataset_guard, depth_guard);