├── README.md ├── examples ├── MonteCarlo.cpp ├── README.md ├── blackscholes.cpp ├── find_if.cpp ├── histogram.cpp ├── palindrome.cpp ├── prime.cpp ├── sort.cpp ├── stable_sort.cpp ├── sum_reduction.cpp └── user_policies.cpp ├── include └── experimental │ ├── algorithm │ ├── bits │ └── parallel │ │ ├── algos │ │ ├── par │ │ │ ├── all_of.h │ │ │ ├── any_of.h │ │ │ ├── count.h │ │ │ ├── count_if.h │ │ │ ├── diffract.h │ │ │ ├── fill.h │ │ │ ├── fill_n.h │ │ │ ├── find.h │ │ │ ├── find_if.h │ │ │ ├── find_if_not.h │ │ │ ├── for_each.h │ │ │ ├── for_each_n.h │ │ │ ├── generate.h │ │ │ ├── generate_n.h │ │ │ ├── is_heap.h │ │ │ ├── is_heap_until.h │ │ │ ├── is_sorted.h │ │ │ ├── max_element.h │ │ │ ├── min_element.h │ │ │ ├── minmax_element.h │ │ │ ├── none_of.h │ │ │ ├── reduce.h │ │ │ ├── replace.h │ │ │ ├── replace_if.h │ │ │ ├── sort.h │ │ │ └── stable_sort.h │ │ └── seq │ │ │ ├── adjacent_difference.h │ │ │ ├── adjacent_find.h │ │ │ ├── all_of.h │ │ │ ├── any_of.h │ │ │ ├── copy.h │ │ │ ├── copy_if.h │ │ │ ├── copy_n.h │ │ │ ├── count.h │ │ │ ├── count_if.h │ │ │ ├── equal.h │ │ │ ├── exclusive_scan.h │ │ │ ├── fill.h │ │ │ ├── fill_n.h │ │ │ ├── find.h │ │ │ ├── find_end.h │ │ │ ├── find_first_of.h │ │ │ ├── find_if.h │ │ │ ├── find_if_not.h │ │ │ ├── for_each.h │ │ │ ├── for_each_n.h │ │ │ ├── generate.h │ │ │ ├── generate_n.h │ │ │ ├── includes.h │ │ │ ├── inclusive_scan.h │ │ │ ├── inner_product.h │ │ │ ├── inplace_merge.h │ │ │ ├── is_heap.h │ │ │ ├── is_heap_until.h │ │ │ ├── is_partitioned.h │ │ │ ├── is_sorted.h │ │ │ ├── is_sorted_until.h │ │ │ ├── lexicographical_compare.h │ │ │ ├── max_element.h │ │ │ ├── merge.h │ │ │ ├── min_element.h │ │ │ ├── minmax_element.h │ │ │ ├── mismatch.h │ │ │ ├── move.h │ │ │ ├── none_of.h │ │ │ ├── nth_element.h │ │ │ ├── partial_sort.h │ │ │ ├── partial_sort_copy.h │ │ │ ├── partition.h │ │ │ ├── partition_copy.h │ │ │ ├── partition_point.h │ │ │ ├── reduce.h │ │ │ ├── remove.h │ │ │ ├── remove_copy.h │ │ │ ├── remove_copy_if.h │ │ │ ├── remove_if.h │ │ │ ├── replace.h │ │ │ ├── replace_copy.h │ │ │ ├── replace_copy_if.h │ │ │ ├── replace_if.h │ │ │ ├── reverse.h │ │ │ ├── reverse_copy.h │ │ │ ├── rotate.h │ │ │ ├── rotate_copy.h │ │ │ ├── search.h │ │ │ ├── search_n.h │ │ │ ├── set_difference.h │ │ │ ├── set_intersection.h │ │ │ ├── set_symmetric_difference.h │ │ │ ├── set_union.h │ │ │ ├── sort.h │ │ │ ├── stable_partition.h │ │ │ ├── stable_sort.h │ │ │ ├── swap_ranges.h │ │ │ ├── transform.h │ │ │ ├── unique.h │ │ │ └── unique_copy.h │ │ ├── policy_dynamic.h │ │ ├── policy_parallel.h │ │ └── policy_sequential.h │ ├── execution_policy │ └── numeric ├── prototypes └── user_policy.cpp └── test ├── CMakeLists.txt ├── README.md ├── alg.modifying.operations ├── alg.gen.copy │ ├── copy.cpp │ ├── copy_if.cpp │ └── copy_n.cpp ├── alg.gen.fill │ ├── fill.cpp │ └── fill_n.cpp ├── alg.gen.generate │ ├── generate.cpp │ └── generate_n.cpp ├── alg.gen.move │ └── move.cpp ├── alg.gen.partitions │ ├── is_partitioned.cpp │ ├── partition.cpp │ ├── partition_copy.cpp │ ├── partition_point.cpp │ └── stable_partition.cpp ├── alg.gen.remove │ ├── remove.cpp │ ├── remove_copy.cpp │ ├── remove_copy_if.cpp │ └── remove_if.cpp ├── alg.gen.replace │ ├── replace.cpp │ ├── replace_copy.cpp │ ├── replace_copy_if.cpp │ └── replace_if.cpp ├── alg.gen.reverse │ ├── reverse.cpp │ └── reverse_copy.cpp ├── alg.gen.rotate │ ├── rotate.cpp │ └── rotate_copy.cpp ├── alg.gen.swap │ └── swap_ranges.cpp ├── alg.gen.transform │ ├── binary_transform.cpp │ └── unary_transform.cpp ├── alg.gen.unique │ ├── unique.cpp │ └── unique_copy.cpp ├── alg.numerics.adjacent.difference │ └── adjacent_difference.cpp ├── alg.numerics.exclusive.scan │ └── exclusive_scan.cpp └── alg.numerics.inclusive.scan │ └── inclusive_scan.cpp ├── alg.nonmodifying ├── alg.gen.adjacent.find │ └── adjacent_find.cpp ├── alg.gen.all_of │ └── all_of.cpp ├── alg.gen.any_of │ └── any_of.cpp ├── alg.gen.count │ ├── count.cpp │ └── count_if.cpp ├── alg.gen.equal │ └── equal.cpp ├── alg.gen.find.end │ └── find_end.cpp ├── alg.gen.find.first.of │ └── find_first_of.cpp ├── alg.gen.find │ ├── find.cpp │ ├── find_if.cpp │ └── find_if_not.cpp ├── alg.gen.foreach │ ├── for_each.cpp │ └── for_each_n.cpp ├── alg.gen.heap │ ├── is_heap.cpp │ └── is_heap_until.cpp ├── alg.gen.mismatch │ └── mismatch.cpp ├── alg.gen.none_of │ └── none_of.cpp ├── alg.gen.search │ ├── search.cpp │ └── search_n.cpp ├── alg.numerics.inner.product │ └── inner_product.cpp └── alg.numerics.reduce │ └── reduce.cpp └── alg.sorting ├── alg.gen.lex.comparison └── lexicographical_compare.cpp ├── alg.gen.merge ├── inplace_merge.cpp └── merge.cpp ├── alg.gen.min.max ├── max_element.cpp ├── min_element.cpp └── minmax_element.cpp ├── alg.gen.nth.element └── nth_element.cpp ├── alg.gen.set.operations ├── includes │ └── includes.cpp ├── set.difference │ └── set_difference.cpp ├── set.intersection │ └── set_intersection.cpp ├── set.symmetric.difference │ └── set_symmetric_difference.cpp └── set.union │ └── set_union.cpp └── alg.gen.sort ├── is.sorted ├── is_sorted.cpp └── is_sorted_until.cpp ├── partial.sort.copy └── partial_sort_copy.cpp ├── partial.sort └── partial_sort.cpp ├── sort └── sort.cpp └── stable.sort └── stable_sort.cpp /README.md: -------------------------------------------------------------------------------- 1 | # N4354 Implementation 2 | 3 | ### Overview 4 | 5 | This repository contains a parallel version of the STL algorithms as a proof of concept for a C++ extension proposal. It was filed as n3554 and then became [n3850](http://isocpp.org/blog/2014/01/n3850), then [n3960](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3960.pdf), then N4354 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4354.pdf). 6 | 7 | This project is in a very early stage. We plan to first implement an integration suite based on the current STL algorithms, then implement the sequential policy and finally a parallel policy based on std::thread. 8 | 9 | We will also try to draft a documentation in the wiki, largely inspired by the [cppreference](http://en.cppreference.com) website. 10 | 11 | The goal is to make is as easy as possible for people to implement and test their own execution policies, once the standard parallel and sequential ones are implemented. 12 | 13 | ### Reference 14 | 15 | * [Official TS](http://isocpp.org/blog/2014/01/n3850), most recent one [here](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3960.pdf). 16 | * [Jared Hoberock's implementation](https://github.com/n3554/n3554) based on thrust. 17 | * [Microsoft's implementation](https://parallelstl.codeplex.com) using Windows Foundation utilities. 18 | * [GCC's parallel implementation](http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html) of the STL algorithms. 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/MonteCarlo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | double test_pi() { 11 | thread_local static random_device rd; 12 | 13 | constexpr unsigned samples = 10000; 14 | mt19937_64 gen(rd()); 15 | uniform_real_distribution dis(0,1); 16 | 17 | unsigned sum = 0; 18 | for(unsigned i = 0; i < samples; ++i){ 19 | const double x = dis(gen), y = dis(gen); 20 | double dist = sqrtf(x*x + y*y); 21 | if(dist <= 1.0f) 22 | sum++; 23 | } 24 | 25 | sum *= 4; 26 | return static_cast(sum)/static_cast(samples); 27 | } 28 | 29 | template 30 | auto extimate_pi(T && policy) 31 | -> std::chrono::microseconds 32 | { 33 | using namespace std::experimental; 34 | constexpr unsigned samples = 10000; 35 | vector estimates(samples); 36 | 37 | auto start = chrono::high_resolution_clock::now(); 38 | 39 | parallel::generate(policy, begin(estimates), end(estimates), test_pi); 40 | auto pi = parallel::reduce(policy, begin(estimates), end(estimates)) / double{samples}; 41 | 42 | auto finish = chrono::high_resolution_clock::now(); 43 | 44 | cout << "pi = " << pi << endl; 45 | 46 | return chrono::duration_cast(finish-start); 47 | } 48 | 49 | int main(){ 50 | using namespace std::experimental; 51 | cout << "Using seq: " << endl; 52 | auto time_seq = extimate_pi(parallel::seq); 53 | cout << "seq took " << time_seq.count() << " us" << endl; 54 | 55 | cout << "Using par: " << endl; 56 | auto time_par = extimate_pi(parallel::par); 57 | cout << "seq took " << time_par.count() << " us" << endl; 58 | } 59 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example applications using parallel standard algorithms 2 | 3 | ## Compilation 4 | 5 | To compile the code, add the include directory from the root to the include path, make sure you have C++11 enabled and link with the thread library if necessary: 6 | 7 | ``` 8 | #!c++ 9 | $> g++ -O3 -std=c++11 -I../include -o bs blackscholes.cpp -lpthread 10 | $> ./bs 11 | Using seq: 1609520 us 12 | Using par: 130504 us 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /examples/blackscholes.cpp: -------------------------------------------------------------------------------- 1 | // adapted from http://www.espenhaug.com/black_scholes.html 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | constexpr double PI =3.141592653589793238463; 9 | 10 | // The cumulative normal distribution function 11 | double CND( double X ) 12 | { 13 | double L, K, w ; 14 | 15 | double const a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937; 16 | double const a4 = -1.821255978, a5 = 1.330274429; 17 | 18 | L = fabs(X); 19 | K = 1.0 / (1.0 + 0.2316419 * L); 20 | w = 1.0 - 1.0 / sqrt(2 * PI) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3 * pow(K,3) + a4 * pow(K,4) + a5 * pow(K,5)); 21 | 22 | if (X < 0 ){ 23 | w= 1.0 - w; 24 | } 25 | return w; 26 | } 27 | 28 | struct Option { 29 | // members to compute 30 | double call, put; 31 | // compute parameters 32 | double S, X, T, r, v; 33 | }; 34 | 35 | // This should be converted to a dynamic policy when they are implemented 36 | template 37 | auto BlackScholes(T && policy, const std::vector