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?" * 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]] [[cpp-standards]]
==== C++ standards ==== C++ standards

View File

@@ -56,6 +56,7 @@ class PathProperties:
# For some reason QEMU fails with SIGSEGV on int syscalls in x86_64. # For some reason QEMU fails with SIGSEGV on int syscalls in x86_64.
'qemu_x86_64_int_syscall': False, 'qemu_x86_64_int_syscall': False,
'interactive': False, 'interactive': False,
'minimum_gcc_version': (0, 0, 0),
# The script takes a perceptible amount of time to run. Possibly an infinite loop. # The script takes a perceptible amount of time to run. Possibly an infinite loop.
'more_than_1s': False, 'more_than_1s': False,
# The path should not be built. E.g., it is symlinked into multiple archs. # 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. Encodes properties of userland and baremetal paths.
For directories, it applies to all files under the directory. For directories, it applies to all files under the directory.
@@ -227,6 +231,8 @@ class PathProperties:
'cpus' in self['test_run_args'] and 'cpus' in self['test_run_args'] and
self['test_run_args']['cpus'] > 1 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}, 'count.cpp': {'more_than_1s': True},
'parallel_sort.cpp': {'minimum_gcc_version': (9, 0, 0)},
'sleep_for.cpp': { 'sleep_for.cpp': {
'more_than_1s': True, '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) { int main(int argc, char **argv) {
// Potentially expensive /dev/urandom read that waits for entropy. // Potentially expensive /dev/urandom read that waits for entropy.
std::random_device dev; 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<uint64_t> zero_ull_max(0);
std::uniform_int_distribution<uint8_t> one_to_six(1, 6); std::uniform_int_distribution<uint8_t> one_to_six(1, 6);