mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
c++ parallel sort algorithm example
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
51
userland/cpp/parallel_sort.cpp
Normal file
51
userland/cpp/parallel_sort.cpp
Normal 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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user