c++ parallel sort algorithm example

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-12-02 00:00:00 +00:00
parent 998e37aa42
commit 7b74328603
4 changed files with 67 additions and 1 deletions

View File

@@ -14020,6 +14020,13 @@ Bibliography:
* https://stackoverflow.com/questions/31978324/what-exactly-is-stdatomic/58904448#58904448 "What exactly is std::atomic?"
[[cpp-parallel-algorithms]]
===== C++ parallel algorithms
https://stackoverflow.com/questions/51031060/are-c17-parallel-algorithms-implemented-already/55989883#55989883
link:userland/cpp/parallel_sort.cpp[]
[[cpp-standards]]
==== C++ standards

View File

@@ -56,6 +56,7 @@ class PathProperties:
# For some reason QEMU fails with SIGSEGV on int syscalls in x86_64.
'qemu_x86_64_int_syscall': False,
'interactive': False,
'minimum_gcc_version': (0, 0, 0),
# The script takes a perceptible amount of time to run. Possibly an infinite loop.
'more_than_1s': False,
# The path should not be built. E.g., it is symlinked into multiple archs.
@@ -153,6 +154,9 @@ class PathProperties:
},
}
# TODO maybe extract automatically from GCC executable?
current_gcc_version = (7, 3, 0)
'''
Encodes properties of userland and baremetal paths.
For directories, it applies to all files under the directory.
@@ -227,6 +231,8 @@ class PathProperties:
'cpus' in self['test_run_args'] and
self['test_run_args']['cpus'] > 1
)
) and not (
self['minimum_gcc_version'] > self.current_gcc_version
)
)
@@ -631,6 +637,7 @@ path_properties_tuples = (
},
),
'count.cpp': {'more_than_1s': True},
'parallel_sort.cpp': {'minimum_gcc_version': (9, 0, 0)},
'sleep_for.cpp': {
'more_than_1s': True,
},

View File

@@ -0,0 +1,51 @@
// https://cirosantilli.com/linux-kernel-module-cheat#cpp-parallel-algorithms
#include <algorithm>
#include <cassert>
#include <chrono>
#include <execution>
#include <random>
#include <iostream>
#include <vector>
int main(int argc, char **argv) {
using clk = std::chrono::high_resolution_clock;
decltype(clk::now()) start, end;
std::vector<unsigned long long> input_parallel, input_serial;
unsigned int seed;
unsigned long long n;
// CLI arguments;
std::uniform_int_distribution<uint64_t> zero_ull_max(0);
if (argc > 1) {
n = std::strtoll(argv[1], NULL, 0);
} else {
n = 10;
}
if (argc > 2) {
seed = std::stoi(argv[2]);
} else {
seed = std::random_device()();
}
// Calculate random inpu.
std::mt19937 prng(seed);
for (unsigned long long i = 0; i < n; ++i) {
input_parallel.push_back(zero_ull_max(prng));
}
input_serial = input_parallel;
// Sort and time parallel.
start = clk::now();
std::sort(std::execution::par_unseq, input_parallel.begin(), input_parallel.end());
end = clk::now();
std::cout << "parallel " << std::chrono::duration<float>(end - start).count() << " s" << std::endl;
// Sort and time serial.
start = clk::now();
std::sort(std::execution::seq, input_serial.begin(), input_serial.end());
end = clk::now();
std::cout << "serial " << std::chrono::duration<float>(end - start).count() << " s" << std::endl;
assert(input_parallel == input_serial);
}

View File

@@ -6,7 +6,8 @@
int main(int argc, char **argv) {
// Potentially expensive /dev/urandom read that waits for entropy.
std::random_device dev;
std::mt19937 prng(dev());
auto seed = dev();
std::mt19937 prng(seed);
std::uniform_int_distribution<uint64_t> zero_ull_max(0);
std::uniform_int_distribution<uint8_t> one_to_six(1, 6);