FEATURE: fully support of untuned parallel algorithm
This commit is contained in:
parent
038ef8f439
commit
12f71c5d7e
@ -292,42 +292,50 @@ namespace algo {
|
|||||||
|
|
||||||
template<typename T, typename Comparator>
|
template<typename T, typename Comparator>
|
||||||
static auto
|
static auto
|
||||||
merge(typename std::vector<T>::iterator mid, std::vector<T> &left, std::vector<T> &right,
|
merge(std::vector<T> left, std::vector<T> right,
|
||||||
Comparator cmp, std::mutex &mut) {
|
Comparator cmp, std::mutex &mut) -> std::vector<T> {
|
||||||
|
|
||||||
|
std::vector<T> output;
|
||||||
|
output.reserve(left.size() + right.size());
|
||||||
|
|
||||||
auto l = left.begin();
|
auto l = left.begin();
|
||||||
auto r = right.begin();
|
auto r = right.begin();
|
||||||
|
|
||||||
|
auto o = output.begin();
|
||||||
|
|
||||||
while (l < left.end() && r < right.end()) {
|
while (l < left.end() && r < right.end()) {
|
||||||
if (cmp(*l, *r)) {
|
if (cmp(*l, *r)) {
|
||||||
*mid = *l;
|
output.insert(o, *l);
|
||||||
l++;
|
l++;
|
||||||
} else {
|
} else {
|
||||||
*mid = *r;
|
output.insert(o, *r);
|
||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
mid++;
|
o++;
|
||||||
}
|
}
|
||||||
while (l < left.end()) {
|
while (l < left.end()) {
|
||||||
*mid = *l;
|
output.insert(o, *l);
|
||||||
mid++;
|
o++;
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
while (r < right.end()) {
|
while (r < right.end()) {
|
||||||
*mid = *r;
|
output.insert(o, *r);
|
||||||
mid++;
|
o++;
|
||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Comparator>
|
template<typename T, typename Comparator>
|
||||||
static auto split(std::vector<T> &data, std::vector<T> &output, Comparator cmp, int depth, int &num_threads,
|
static auto split(std::vector<T> data, Comparator cmp, int depth, int &num_threads,
|
||||||
std::mutex &mut) {
|
std::mutex &mut) -> std::vector<T>{
|
||||||
if (data.size() <= 1) {
|
if (data.size() <= 1) {
|
||||||
return;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<T> output;
|
||||||
|
output.reserve(data.size());
|
||||||
|
|
||||||
auto mid = data.begin();
|
auto mid = data.begin();
|
||||||
std::advance(mid, std::distance(data.begin(), data.end()) / 2);
|
std::advance(mid, std::distance(data.begin(), data.end()) / 2);
|
||||||
|
|
||||||
@ -336,43 +344,29 @@ namespace algo {
|
|||||||
std::vector<T> right(mid, data.end());
|
std::vector<T> right(mid, data.end());
|
||||||
|
|
||||||
if (depth < num_threads) {
|
if (depth < num_threads) {
|
||||||
std::thread left_thread([&]() { split(left, output, cmp, depth + 1, num_threads, mut); });
|
std::thread left_thread([&]() { left = split(left, cmp, depth + 1, num_threads, mut); });
|
||||||
std::thread right_thread([&]() { split(right, output, cmp, depth + 1, num_threads, mut); });
|
std::thread right_thread([&]() { right = split(right, cmp, depth + 1, num_threads, mut); });
|
||||||
|
|
||||||
left_thread.join();
|
left_thread.join();
|
||||||
right_thread.join();
|
right_thread.join();
|
||||||
} else {
|
} else {
|
||||||
split(left, output, cmp, depth + 1, num_threads, mut);
|
left = split(left, cmp, depth + 1, num_threads, mut);
|
||||||
split(right, output, cmp, depth + 1, num_threads, mut);
|
right = split(right, cmp, depth + 1, num_threads, mut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return merge(left, right, cmp, mut);
|
||||||
mid = output.begin();
|
|
||||||
std::advance(mid, std::distance(output.begin(), output.end()) / 2);
|
|
||||||
|
|
||||||
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:
|
||||||
template<typename T, typename Comparator>
|
template<typename T, typename Comparator>
|
||||||
static auto
|
static auto
|
||||||
sort(std::vector<T> &data, Comparator cmp, int num_threads = std::thread::hardware_concurrency()) -> void {
|
sort(std::vector<T> &data, Comparator cmp, int num_threads = std::thread::hardware_concurrency()) -> void {
|
||||||
std::vector<T> local_result = data;
|
|
||||||
std::mutex local_result_lock;
|
std::mutex local_result_lock;
|
||||||
|
std::vector<T> output;
|
||||||
|
output.reserve(data.size());
|
||||||
|
|
||||||
split(data, local_result, cmp, 0, num_threads, local_result_lock);
|
output = split(data, cmp, 0, num_threads, local_result_lock);
|
||||||
data = local_result;
|
data.assign(output.begin(), output.end());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user