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 #ifndef EIGEN_PARALLELIZER_H
00026 #define EIGEN_PARALLELIZER_H
00027
00028 namespace internal {
00029
00031 inline void manage_multi_threading(Action action, int* v)
00032 {
00033 static EIGEN_UNUSED int m_maxThreads = -1;
00034
00035 if(action==SetAction)
00036 {
00037 eigen_internal_assert(v!=0);
00038 m_maxThreads = *v;
00039 }
00040 else if(action==GetAction)
00041 {
00042 eigen_internal_assert(v!=0);
00043 #ifdef EIGEN_HAS_OPENMP
00044 if(m_maxThreads>0)
00045 *v = m_maxThreads;
00046 else
00047 *v = omp_get_max_threads();
00048 #else
00049 *v = 1;
00050 #endif
00051 }
00052 else
00053 {
00054 eigen_internal_assert(false);
00055 }
00056 }
00057
00060 inline int nbThreads()
00061 {
00062 int ret;
00063 manage_multi_threading(GetAction, &ret);
00064 return ret;
00065 }
00066
00069 inline void setNbThreads(int v)
00070 {
00071 manage_multi_threading(SetAction, &v);
00072 }
00073
00074 template<typename Index> struct GemmParallelInfo
00075 {
00076 GemmParallelInfo() : sync(-1), users(0), rhs_start(0), rhs_length(0) {}
00077
00078 int volatile sync;
00079 int volatile users;
00080
00081 Index rhs_start;
00082 Index rhs_length;
00083 };
00084
00085 template<bool Condition, typename Functor, typename Index>
00086 void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpose)
00087 {
00088 #ifndef EIGEN_HAS_OPENMP
00089
00090
00091
00092
00093 EIGEN_UNUSED_VARIABLE(transpose);
00094 func(0,rows, 0,cols);
00095 #else
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 if((!Condition) || (omp_get_num_threads()>1))
00106 return func(0,rows, 0,cols);
00107
00108 Index size = transpose ? cols : rows;
00109
00110
00111
00112 Index max_threads = std::max<Index>(1,size / 32);
00113
00114
00115 Index threads = std::min<Index>(nbThreads(), max_threads);
00116
00117 if(threads==1)
00118 return func(0,rows, 0,cols);
00119
00120 func.initParallelSession();
00121
00122 if(transpose)
00123 std::swap(rows,cols);
00124
00125 Index blockCols = (cols / threads) & ~Index(0x3);
00126 Index blockRows = (rows / threads) & ~Index(0x7);
00127
00128 GemmParallelInfo<Index>* info = new GemmParallelInfo<Index>[threads];
00129
00130 #pragma omp parallel for schedule(static,1) num_threads(threads)
00131 for(Index i=0; i<threads; ++i)
00132 {
00133 Index r0 = i*blockRows;
00134 Index actualBlockRows = (i+1==threads) ? rows-r0 : blockRows;
00135
00136 Index c0 = i*blockCols;
00137 Index actualBlockCols = (i+1==threads) ? cols-c0 : blockCols;
00138
00139 info[i].rhs_start = c0;
00140 info[i].rhs_length = actualBlockCols;
00141
00142 if(transpose)
00143 func(0, cols, r0, actualBlockRows, info);
00144 else
00145 func(r0, actualBlockRows, 0,cols, info);
00146 }
00147
00148 delete[] info;
00149 #endif
00150 }
00151
00152 }
00153
00154 #endif // EIGEN_PARALLELIZER_H