par_loop.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _GLIBCXX_PARALLEL_PAR_LOOP_H
00034 #define _GLIBCXX_PARALLEL_PAR_LOOP_H 1
00035
00036 #include <omp.h>
00037 #include <parallel/settings.h>
00038 #include <parallel/base.h>
00039 #include <parallel/equally_split.h>
00040
00041 namespace __gnu_parallel
00042 {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template<typename RandomAccessIterator,
00063 typename Op,
00064 typename Fu,
00065 typename Red,
00066 typename Result>
00067 Op
00068 for_each_template_random_access_ed(RandomAccessIterator begin,
00069 RandomAccessIterator end,
00070 Op o, Fu& f, Red r, Result base,
00071 Result& output,
00072 typename std::iterator_traits
00073 <RandomAccessIterator>::
00074 difference_type bound)
00075 {
00076 typedef std::iterator_traits<RandomAccessIterator> traits_type;
00077 typedef typename traits_type::difference_type difference_type;
00078 const difference_type length = end - begin;
00079 Result *thread_results;
00080 bool* constructed;
00081
00082 thread_index_t num_threads =
00083 __gnu_parallel::min<difference_type>(get_max_threads(), length);
00084
00085 # pragma omp parallel num_threads(num_threads)
00086 {
00087 # pragma omp single
00088 {
00089 num_threads = omp_get_num_threads();
00090 thread_results = static_cast<Result*>(
00091 ::operator new(num_threads * sizeof(Result)));
00092 constructed = new bool[num_threads];
00093 }
00094
00095 thread_index_t iam = omp_get_thread_num();
00096
00097
00098 Result* reduct = static_cast<Result*>(::operator new(sizeof(Result)));
00099
00100 difference_type
00101 start = equally_split_point(length, num_threads, iam),
00102 stop = equally_split_point(length, num_threads, iam + 1);
00103
00104 if (start < stop)
00105 {
00106 new(reduct) Result(f(o, begin + start));
00107 ++start;
00108 constructed[iam] = true;
00109 }
00110 else
00111 constructed[iam] = false;
00112
00113 for (; start < stop; ++start)
00114 *reduct = r(*reduct, f(o, begin + start));
00115
00116 thread_results[iam] = *reduct;
00117 }
00118
00119 for (thread_index_t i = 0; i < num_threads; ++i)
00120 if (constructed[i])
00121 output = r(output, thread_results[i]);
00122
00123
00124
00125 f.finish_iterator = begin + length;
00126
00127 delete[] thread_results;
00128 delete[] constructed;
00129
00130 return o;
00131 }
00132
00133 }
00134
00135 #endif