C++ (Qt)#ifndef PARALLEL_H#define PARALLEL_H #include <algorithm>#include <thread>#include <memory>#include <iterator>#include <vector> struct parallel{ template<class InputIt, class OutputIt, class UnaryOperation> static OutputIt transform(InputIt ifirst, InputIt ilast, OutputIt ofirst, UnaryOperation unary_op) { const size_t size = std::distance(ifirst, ilast); const size_t nthreads = std::min(size, static_cast<size_t>(std::thread::hardware_concurrency())); if (nthreads < 2) return std::transform(ifirst, ilast, ofirst, unary_op); const size_t group = size/nthreads; std::vector<std::shared_ptr<std::thread>> threads(nthreads-1); auto it = ifirst; for (auto & thread_ptr : threads) { std::advance(it, group); thread_ptr = std::make_shared<std::thread>([=]{ std::transform(ifirst, it, ofirst, unary_op); }); ifirst = it; std::advance(ofirst, group); } for (auto & t : threads) { t->join(); } return std::transform(ifirst, ilast, ofirst, unary_op); } template<class InputIt1, class InputIt2, class OutputIt, class BinaryOperation> static OutputIt transform(InputIt1 ifirst1, InputIt1 ilast1, InputIt2 ifirst2, OutputIt ofirst, BinaryOperation binary_op) { const size_t size = std::distance(ifirst1, ilast1); const size_t nthreads = std::min(size, static_cast<size_t>(std::thread::hardware_concurrency())); if (nthreads < 2) return std::transform(ifirst1, ilast1, ifirst2, ofirst, binary_op); const size_t group = size/nthreads; std::vector<std::shared_ptr<std::thread>> threads(nthreads-1); auto it = ifirst1; for (auto & thread_ptr : threads) { std::advance(it, group); thread_ptr = std::make_shared<std::thread>([=]{ std::transform(ifirst1, it, ifirst2, ofirst, binary_op); }); ifirst1 = it; std::advance(ifirst2, group); std::advance(ofirst, group); } for (auto & t : threads) { t->join(); } return std::transform(ifirst1, ilast1, ifirst2, ofirst, binary_op); }}; #endif // PARALLEL_H
C++ (Qt)#include <iostream>#include <vector>#include <cmath>#include <chrono> #include "parallel.h" double func(const double & x) { return sin(x)*cos(x*x)*exp(-x*x*0.5)/(1.0 + x*x);} int main(){ const size_t N = 10000000; std::vector<double> v1(N, 2.0); std::vector<double> v2(v1); auto start = std::chrono::high_resolution_clock::now(); parallel::transform(v1.begin(), v1.end(), v2.begin(), func); auto stop = std::chrono::high_resolution_clock::now(); auto par_duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count(); start = std::chrono::high_resolution_clock::now(); std::transform(v1.begin(), v1.end(), v2.begin(), func); stop = std::chrono::high_resolution_clock::now(); auto seq_duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count(); std::cout << "par: " << par_duration << std::endl; std::cout << "seq: " << seq_duration << std::endl; return 0;}
C++ (Qt)... ofirst = std::transform(ifirst, ilast, ofirst, unary_op); for (auto & t : threads) { t->join(); } return ofirst;
C++ (Qt) const size_t group = size/nthreads; std::vector<std::shared_ptr<std::thread>> threads(nthreads-1); auto it = ifirst; for (auto & thread_ptr : threads) { std::advance(it, group); thread_ptr = std::make_shared<std::thread>([=]{ std::transform(ifirst, it, ofirst, unary_op); }); ifirst = it; std::advance(ofirst, group); }
C++ (Qt)size_t need = 0, fact = 0;for (size_t i = 0; i < nthread - 1; ++i) { need = (i + 1) * num_Tasks / nthread; // 1, 3, 5 num = need - fact; // 1, 2, 2 fact = need; std::advance(it, num); ... }
C++ (Qt)double func(const double & x) { double result = sin(x)*cos(x*x)*exp(-x*x*0.5)/(1.0 + x*x); ++atomic_count; if (m_master) if (!UpdateUI(atomic_count)) SetAbortFlag();}
C++ (Qt)const size_t group = std::lround(double(size)/nthreads);
C++ (Qt)std::vector<int> v1(N);std::vector<int> v2; // Пустой!parallel::transform(v1.begin(), v1.end(), std::back_inserter(v2), func);
C++ (Qt)#pragma omp parallel forfor (int i = 0; i < src.size(); ++i) DoCalc(src[i], dst[i]);
C++ (Qt)typedef typename std::iterator_traits<OutputIt>::iterator_category iterator_category;static_assert(std::is_base_of<std::forward_iterator_tag, iterator_category>::value, "iterator must meet all the requirements for forward iterator");
C++ (Qt)... const size_t normal_group = size/nthreads; const size_t m = size - normal_group * nthreads; size_t i = 0; for (auto & thread_ptr : threads) { size_t group = (++i <= m) ? normal_group + 1 : normal_group; std::advance(it, group); ... }