From 70f4290b3c419d8e8fd6f7286efaac8a85ed8ead Mon Sep 17 00:00:00 2001 From: nihonium Date: Sat, 18 Mar 2023 19:24:37 +0300 Subject: [PATCH] parallel max --- .../seminar_thread/00problem_paralel_max.cpp | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 term2/seminar_thread/00problem_paralel_max.cpp diff --git a/term2/seminar_thread/00problem_paralel_max.cpp b/term2/seminar_thread/00problem_paralel_max.cpp new file mode 100644 index 0000000..712b958 --- /dev/null +++ b/term2/seminar_thread/00problem_paralel_max.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::cout, std::endl, std::size_t, std::vector; +using namespace std::chrono_literals; + +uint64_t get_max(vector::iterator start, vector::iterator end) +{ + uint64_t result = *start; + while (start++ != end) + if (*start > result) + result = *start; + + return result; +} + +struct max_block { + void operator() (vector::iterator start, vector::iterator end, uint64_t& res) { + res = get_max(start, end); + } +}; + +uint64_t parallel_max(vector::iterator start, vector::iterator end) { + int const length = std::distance(start, end); + int const min_per_thread = 25; + int const max_threads = (length + min_per_thread - 1) / min_per_thread; + int const hardware_threads = std::thread::hardware_concurrency(); + int const num_threads = std::min(hardware_threads!=0?hardware_threads:2, max_threads); + int const block_size = length / num_threads; +#ifdef _DEBUG + cout << "num_threads = " << num_threads << endl; +#endif + vector results(num_threads); + vector threads(num_threads - 1); + auto block_start = start; + + for(auto i = 0; i < num_threads - 1; ++i) { + auto block_end = block_start; + std::advance(block_end, block_size); + threads[i] = std::thread(max_block(), block_start, block_end, std::ref(results[i])); + block_start = block_end; + } + + max_block() (block_start, end, results[num_threads - 1]); + + std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join)); + + return get_max(results.begin(), results.end()); + +} + +int main() +{ + cout << "Generating numbers!" << endl; + +#ifdef _DEBUG + std::vector numbers(1000); + numbers[0] = 5; + for (size_t i = 1; i < numbers.size(); ++i) + { + numbers[i] = numbers[i - 1] * i + 1; + + } +#else + std::vector numbers(5e8); + numbers[0] = 123456789; + for (size_t i = 1; i < numbers.size(); ++i) + { + numbers[i] = numbers[i - 1] * i + 1; + } + cout << "Numbers generated!" << endl; +#endif + + auto start1 = std::chrono::high_resolution_clock::now(); + uint64_t m1 = get_max(numbers.begin(), numbers.end()); + auto end1 = std::chrono::high_resolution_clock::now(); + cout << "Maximum = " << m1 << endl; + cout << "Time to calculate max = " << std::chrono::duration_cast(end1 - start1).count() + << " milliseconds." << endl; + + auto start2 = std::chrono::high_resolution_clock::now(); + uint64_t m2 = parallel_max(numbers.begin(), numbers.end()); + auto end2 = std::chrono::high_resolution_clock::now(); + cout << "Maximum = " << m2 << endl; + cout << "Time to calculate max = " << std::chrono::duration_cast(end2 - start2).count() + << " milliseconds." << endl; +}