parallel max iterators
This commit is contained in:
		
							parent
							
								
									032f0c882a
								
							
						
					
					
						commit
						e15996db52
					
				
					 1 changed files with 110 additions and 0 deletions
				
			
		
							
								
								
									
										110
									
								
								term2/seminar01_thread/01problem_paralel_max_iterators.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								term2/seminar01_thread/01problem_paralel_max_iterators.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,110 @@ | ||||||
|  | /*
 | ||||||
|  |     Задача: | ||||||
|  | 
 | ||||||
|  |         В данном примере написана функция шаблонная getMax, которая находит максимум из чисел в некотором контейнере. | ||||||
|  |         При этом вычисления проходят однопоточно. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         Вам нужно написать шаблонную функцию      | ||||||
|  |              | ||||||
|  |             template <typename RandIt> | ||||||
|  |             RandIt getMax(int n, RandIt start, RandIt finish) | ||||||
|  | 
 | ||||||
|  |         которая будет делать то же самое, но только использовать для этого n потоков. | ||||||
|  |         Функция должна принимать на вход количество потоков и два итератора, задающих | ||||||
|  |         диапазон на котором нужно искать максимум. | ||||||
|  |         Известно, что оба итератора являются random access итераторами. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         Проверить, что эта функция будет работать и для других контейнеров и типов хранящихся в них данных. | ||||||
|  |         Например, для: | ||||||
|  | 
 | ||||||
|  |             std::deque<double> d {1.2, 5.1, 8.2, 1.0, 0.2, 5.0, 7.8}; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include <iostream> | ||||||
|  | #include <thread> | ||||||
|  | #include <chrono> | ||||||
|  | #include <vector> | ||||||
|  | #include <list> | ||||||
|  | #include <random> | ||||||
|  | #include <algorithm> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <functional> | ||||||
|  | #include <deque> | ||||||
|  | using std::cout, std::endl, std::size_t; | ||||||
|  | using namespace std::chrono_literals; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template <typename RandIt> | ||||||
|  | RandIt getMax(RandIt start, RandIt finish) | ||||||
|  | { | ||||||
|  |     RandIt maxIt = start; | ||||||
|  |     for (auto it = start; it != finish; ++it) | ||||||
|  |     { | ||||||
|  |         if (*it > *maxIt) | ||||||
|  |             maxIt = it; | ||||||
|  |     } | ||||||
|  |     return maxIt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename RandIt> | ||||||
|  | struct maxBlock { | ||||||
|  |     void operator() (RandIt first, RandIt last, RandIt& res) { | ||||||
|  |         res = getMax(first, last);  | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template <typename RandIt> | ||||||
|  | RandIt getMax(int n, RandIt start, RandIt finish) { | ||||||
|  |     std::vector<RandIt> results(n); | ||||||
|  | 
 | ||||||
|  |     std::vector<std::thread> threads(n - 1);    | ||||||
|  |     unsigned long const block_size =  std::distance(start, finish) / n; | ||||||
|  | 
 | ||||||
|  |     RandIt block_start = start; | ||||||
|  | 
 | ||||||
|  |     for (int i = 0; i < n - 1; ++i) { | ||||||
|  |         RandIt block_end = block_start; | ||||||
|  |         std::advance(block_end, block_size); | ||||||
|  |         threads[i] = std::thread(maxBlock<RandIt>(),  | ||||||
|  |                         block_start, block_end, std::ref(results[i])); | ||||||
|  |         block_start = block_end; | ||||||
|  |     } | ||||||
|  |     maxBlock<RandIt>() (block_start, finish, results[n - 1]); | ||||||
|  | 
 | ||||||
|  |     std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join)); | ||||||
|  | 
 | ||||||
|  |     return *getMax(results.begin(), results.end()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main() | ||||||
|  | { | ||||||
|  |     cout << "Generating numbers!" << endl; | ||||||
|  |     std::deque<uint64_t> numbers; | ||||||
|  |      | ||||||
|  |     numbers.push_back(1); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < 1e7; ++i) | ||||||
|  |     { | ||||||
|  |         numbers.push_back(numbers.back() + 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     cout << "Numbers generated!" << endl; | ||||||
|  | 
 | ||||||
|  |     auto start = std::chrono::high_resolution_clock::now(); | ||||||
|  |     auto it = getMax(numbers.begin(), numbers.end()); | ||||||
|  |     cout << "Maximum = " << *it << endl; | ||||||
|  |     auto end = std::chrono::high_resolution_clock::now(); | ||||||
|  |     cout << "Time to calclulate max = " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() | ||||||
|  |          << " milliseconds." << endl; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     start = std::chrono::high_resolution_clock::now(); | ||||||
|  |     it = getMax(4, numbers.begin(), numbers.end()); | ||||||
|  |     cout << "Maximum = " << *it << endl; | ||||||
|  |     end = std::chrono::high_resolution_clock::now(); | ||||||
|  |     cout << "Time to calclulate max = " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() | ||||||
|  |          << " milliseconds." << endl; | ||||||
|  | } | ||||||
		Reference in a new issue