parallel max
This commit is contained in:
		
							parent
							
								
									611300636a
								
							
						
					
					
						commit
						70f4290b3c
					
				
					 1 changed files with 93 additions and 0 deletions
				
			
		
							
								
								
									
										93
									
								
								term2/seminar_thread/00problem_paralel_max.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								term2/seminar_thread/00problem_paralel_max.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,93 @@ | ||||||
|  | #include <iostream> | ||||||
|  | #include <thread> | ||||||
|  | #include <chrono> | ||||||
|  | #include <vector> | ||||||
|  | #include <random> | ||||||
|  | #include <algorithm> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <functional> | ||||||
|  | 
 | ||||||
|  | using std::cout, std::endl, std::size_t, std::vector; | ||||||
|  | using namespace std::chrono_literals; | ||||||
|  | 
 | ||||||
|  | uint64_t get_max(vector<uint64_t>::iterator start, vector<uint64_t>::iterator end) | ||||||
|  | { | ||||||
|  |     uint64_t result = *start; | ||||||
|  |     while (start++ != end)  | ||||||
|  |         if (*start > result) | ||||||
|  |             result = *start;  | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct max_block { | ||||||
|  |     void operator() (vector<uint64_t>::iterator start, vector<uint64_t>::iterator end, uint64_t& res) { | ||||||
|  |         res = get_max(start, end); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | uint64_t parallel_max(vector<uint64_t>::iterator start, vector<uint64_t>::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<uint64_t> results(num_threads); | ||||||
|  |     vector<std::thread> 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<uint64_t> numbers(1000); | ||||||
|  |     numbers[0] = 5; | ||||||
|  |     for (size_t i = 1; i < numbers.size(); ++i) | ||||||
|  |     { | ||||||
|  |         numbers[i] = numbers[i - 1] * i + 1; | ||||||
|  |      | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |     std::vector<uint64_t> 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<std::chrono::milliseconds>(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<std::chrono::milliseconds>(end2 - start2).count() | ||||||
|  |          << " milliseconds." << endl; | ||||||
|  | } | ||||||
		Reference in a new issue