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
00036 #ifndef MEMORY_BUFFER_THREAD_HEADER
00037 #define MEMORY_BUFFER_THREAD_HEADER
00038
00039
00040 #include "config.h"
00041
00042
00043 #ifdef USE_SSE_INTRINSICS
00044
00045 #include <iostream>
00046 #include <stdexcept>
00047 #include <vector>
00048 #include <emmintrin.h>
00049 #ifdef __SSE3__
00050 #include <pmmintrin.h>
00051 #endif
00052 #ifdef _OPENMP
00053 #include <omp.h>
00054 #endif
00055
00056 namespace mat{
00057
00058 class Memory_aligned {
00059 protected:
00060 inline void * operator new (size_t s) {
00061 void * p = _mm_malloc (s, 16);
00062 if (p == NULL)
00063 throw std::bad_alloc();
00064 else
00065 return p;
00066 }
00067
00068 inline void * operator new[] (size_t s) {
00069 void * p = _mm_malloc (s, 16);
00070 if (p == NULL)
00071 throw std::bad_alloc();
00072 else
00073 return p;
00074 }
00075
00076 inline void operator delete (void * p) {
00077 _mm_free(p);
00078 }
00079
00080 inline void operator delete[] (void * p) {
00081 _mm_free(p);
00082 }
00083 };
00084
00085 class Memory_buffer_thread : public Memory_aligned {
00086
00087 private:
00088 static void create();
00089 static Memory_buffer_thread* ptr_to_instance;
00090
00091
00092 static volatile char ptr_to_instance_is_valid;
00093 static unsigned int bufSize;
00094 Memory_buffer_thread(Memory_buffer_thread const &);
00095 protected:
00096 Memory_buffer_thread() {}
00097
00098 public:
00099 static Memory_buffer_thread& instance();
00100 template<typename T>
00101 void get_buffer(size_t size, T* & buffer) const {
00102 if (sizeof(T) * size > bufSize)
00103 throw std::runtime_error("In Memory_buffer_thread::get_buffer : "
00104 "Allocated buffer smaller than requested "
00105 "buffer size");
00106 int threadID = 0;
00107 #ifdef _OPENMP
00108 for (int ind = 0; ind <= omp_get_level(); ind++) {
00109 int tmp = omp_get_ancestor_thread_num(ind);
00110 threadID = threadID > tmp ? threadID : tmp;
00111 }
00112 #endif
00113 if (buffers.empty())
00114 throw std::runtime_error("In Memory_buffer_thread::get_buffer : "
00115 "buffers empty!");
00116 if ((unsigned)threadID >= buffers.size())
00117 throw std::runtime_error("In Memory_buffer_thread::get_buffer : "
00118 "thread id larger than number of buffers");
00119 buffer = (T*)buffers[threadID];
00120 }
00121 void init_buffers(unsigned int const nThreads);
00122 ~Memory_buffer_thread();
00123 private:
00124 std::vector<char*> buffers;
00125
00126 };
00127
00128
00129 }
00130
00131 #endif
00132
00133 #endif