auto TotalThreads = std::thread::hardware_concurrency();
template<class Iter, class Pred>
void quick_merge_sort(Iter first, Iter last, Pred pred)
{
auto length = last - first;
auto chunkSize = length / TotalThreads;
auto chunks = length / chunkSize;
if (chunkSize > 1)
{
auto tail = length - (chunkSize * chunks);
auto hasTail = tail > 0;
auto tailStart = first + chunks * chunkSize;
{
std::deque<std::future<void>> tasks;
for (auto thread = 0; thread < chunks; ++thread) {
auto chunkStart = first + thread * chunkSize;
auto chunkEnd = chunkStart + chunkSize;
tasks.emplace_back(std::async(std::launch::async, &std::sort<Iter, Pred>, chunkStart, chunkEnd, pred));
}
if (hasTail)
std::sort(tailStart, last, pred);
while (chunkSize < length)
{
auto bigChunkStart = first;
auto bigChunkMiddle = bigChunkStart;
auto bigChunkEnd = bigChunkStart;
for (auto thread = 0; thread < chunks; ++thread) {
tasks.pop_front();
bigChunkEnd = bigChunkMiddle + chunkSize;
if (thread % 2) {
tasks.emplace_back(std::async(std::launch::async, &std::inplace_merge<Iter, Pred>, bigChunkStart, bigChunkMiddle, bigChunkEnd, pred));
bigChunkStart = bigChunkEnd;
}
bigChunkMiddle += chunkSize;
}
chunkSize *= 2;
chunks = length / chunkSize;
}
} // ensure tasks completion
if (hasTail) {
std::inplace_merge(first, tailStart, last, pred);
}
}
else if (length > 1) {
std::sort(first, last, pred);
}
assert(std::is_sorted(first, last, pred));
}
}
This code still has range-way to improve CPU threads utilization, but it gave much more benefit of parallelization.
How much threads are used to sort with parallel executor?
Hi,
I tried to use
std::sort(std::execution::parparallel implementation using custom predicate on gigabytes of data.Unfortunately its result gave no much benefit comparably to single-thread
std::sort.Simple custom implementation of merge-sort gave much better benefit:
This code still has range-way to improve CPU threads utilization, but it gave much more benefit of parallelization.
How much threads are used to sort with parallel executor?