00001
00002
00011 #ifndef CXXUTILS_PREFETCH_H
00012 #define CXXUTILS_PREFETCH_H
00013
00014
00015 #include <cstdlib>
00016
00017
00018
00019
00020
00021
00022 #ifndef CXXUTILS_PREFETCH_ADDRESS
00023 # ifdef __GNUC__
00024
00025 # define CXXUTILS_PREFETCH_ADDRESS(ADDR) __builtin_prefetch(ADDR)
00026 # else
00027 # define CXXUTILS_PREFETCH_ADDRESS(ADDR) do {} while(0) // no-op
00028 # endif
00029 #endif
00030
00031
00032 namespace CxxUtils {
00033
00034
00054 enum { CacheLineSize = 64 };
00055
00056
00067 inline
00068 void prefetchOne (const void* address)
00069 {
00070 CXXUTILS_PREFETCH_ADDRESS(address);
00071 }
00072
00073
00078 template <size_t N>
00079 inline
00080 void prefetchN (const void* ptr)
00081 {
00082 const char* pp = reinterpret_cast<const char*> (ptr);
00083
00084
00085 for (size_t i = 0; i < N; i += CacheLineSize)
00086 prefetchOne (pp + i);
00087
00088
00089
00090 prefetchOne (pp + N - 1);
00091 }
00092
00093
00101 template <typename T>
00102 inline
00103 void prefetchObj(const T* ptr)
00104 {
00105 prefetchN<sizeof(T)> (ptr);
00106 }
00107
00123 template <typename Iter>
00124 inline
00125 void prefetchNext (Iter iter, Iter endIter)
00126 {
00127 if (++iter != endIter)
00128 prefetchObj(*iter);
00129 }
00130
00131
00147 template <typename Iter>
00148 inline
00149 void prefetchTwo (Iter iter, Iter endIter)
00150 {
00151 if (iter != endIter) {
00152 prefetchObj(*iter);
00153 if (++iter != endIter) {
00154 prefetchObj(*iter);
00155 }
00156 }
00157 }
00158
00159
00160 }
00161
00162
00163 #endif // not CXXUTILS_PREFETCH_H