00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__VECTOR_THREADS__HPP
00014 #define __MMX__VECTOR_THREADS__HPP
00015 #include <algebramix/vector_unrolled.hpp>
00016 #include <basix/threads.hpp>
00017
00018 namespace mmx {
00019 #define TMPL template<typename C>
00020 #define TMPLX template<typename C, typename X>
00021
00022
00023
00024
00025
00026 template<typename V>
00027 struct vector_threads: public V {
00028 typedef typename V::Naive Naive;
00029 typedef vector_threads<typename V::Aligned> Aligned;
00030 typedef vector_threads<typename V::No_simd> No_simd;
00031 typedef typename V::No_thread No_thread;
00032 };
00033
00034 template<typename F, typename V, typename W>
00035 struct implementation<F,V,vector_threads<W> >:
00036 public implementation<F,V,W> {};
00037
00038
00039
00040
00041
00042 template<typename V, typename W>
00043 struct implementation<vector_abstractions,V,vector_threads<W> >:
00044 public implementation<vector_allocate,V>,
00045 public implementation<vector_abstractions,W>
00046 {
00047 typedef implementation<vector_abstractions,W> Vec;
00048
00049 template<typename Op, typename C>
00050 struct unary_task_rep: public task_rep {
00051 C* dest; const C* s; nat n;
00052 public:
00053 inline unary_task_rep (C* dest2, const C* s2, nat n2):
00054 dest (dest2), s (s2), n (n2) {}
00055 void execute () { Vec::template unary<Op> (dest, s, n); }
00056 };
00057
00058 template<typename Op, typename C> static inline void
00059 unary (C* dest, const C* s, nat n) {
00060 if (n < 256) Vec::template unary<Op> (dest, s, n);
00061 else {
00062 task ts[threads_number];
00063 for (nat id=0; id<threads_number; id++) {
00064 nat i1= (id*n) / threads_number;
00065 nat i2= ((id+1)*n) / threads_number;
00066 ts[id]= new unary_task_rep<Op,C> (dest + i1, s + i1, i2 - i1);
00067 }
00068 threads_execute (ts, threads_number);
00069 for (nat id=0; id<threads_number; id++)
00070 delete ts[id];
00071 }
00072 }
00073
00074 template<typename Op, typename C>
00075 struct binary_task_rep: public task_rep {
00076 C* dest; const C* s1; const C* s2; nat n;
00077 public:
00078 inline binary_task_rep (C* dest2, const C* s1b, const C* s2b, nat n2):
00079 dest (dest2), s1 (s1b), s2 (s2b), n (n2) {}
00080 void execute () { Vec::template binary<Op> (dest, s1, s2, n); }
00081 };
00082
00083 template<typename Op, typename C> static inline void
00084 binary (C* dest, const C* s1, const C* s2, nat n) {
00085 if (n < 256) Vec::template binary<Op> (dest, s1, s2, n);
00086 else {
00087 task ts[threads_number];
00088 for (nat id=0; id<threads_number; id++) {
00089 nat i1= (id*n) / threads_number;
00090 nat i2= ((id+1)*n) / threads_number;
00091 ts[id]= new binary_task_rep<Op,C> (dest + i1, s1 + i1, s2 + i1, i2 - i1);
00092 }
00093 threads_execute (ts, threads_number);
00094 }
00095 }
00096
00097 };
00098
00099 #undef TMPL
00100 #undef TMPLX
00101 }
00102 #endif //__MMX__VECTOR_THREADS__HPP