00001 /* 00002 File: InstArray.h 00003 00004 Function: Instrumented Array for tracking access patterns etc. 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1998-2000, Andrew Willmott 00009 */ 00010 00011 #ifndef __InstArray__ 00012 #define __InstArray__ 00013 00014 #include <iostream.h> 00015 #include "cl/NArray.h" 00016 #include "cl/FileName.h" 00017 00018 class InstArrayStats 00019 { 00020 public: 00021 InstArrayStats(); 00022 00023 Void Reset(); 00024 Void StartTrace(const FileName &fname); 00025 Void StopTrace(); 00026 Void Dump(); 00027 00028 Void Read(Int i); 00029 Void Write(Int i); 00030 00031 Int reads; 00032 Int writes; 00033 Int *accesses; 00034 00035 FILE *trace; 00036 }; 00037 00038 #ifdef CL_INST_RW 00039 // this will break on some accesses, because I don't have the patience 00040 // to implement all the +=, *=, etc. operators. Also, it adds considerable 00041 // overhead to reads & writes, so if you don't care about access type, 00042 // you're better off without it. 00043 00044 template <class T> struct RWHelper 00045 { 00046 RWHelper(InstArrayStats &s, Int i, T &e) : stats(s), idx(i), elem(e) {}; 00047 00048 operator T() 00049 { stats.Read(idx); return(elem); }; 00050 T &operator = (const T &rhs) 00051 { stats.Write(idx); elem = rhs; return(elem); }; 00052 T &operator += (const T &rhs) 00053 { stats.Write(idx); elem += rhs; return(elem); }; 00054 00055 InstArrayStats &stats; 00056 Int idx; 00057 T &elem; 00058 }; 00059 #endif 00060 00061 template <class T> class InstArray : public NArray<T> 00062 { 00063 public: 00064 InstArray() : NArray<T>() {}; 00065 InstArray(Int size, Int alloc = kFirstNAllocation) : 00066 NArray<T>(size, alloc) {}; 00067 00068 #ifdef CL_INST_RW 00069 inline RWHelper<T> operator [] (Int i); 00070 #else 00071 inline T &operator [] (Int i); 00072 #endif 00073 inline const T &operator [] (Int i) const; 00074 00075 inline Void Append(const T &t); 00076 inline T &Last(); 00077 inline const T &Last() const; 00078 00079 inline T &Top(); 00080 inline const T &Top() const; 00081 inline Void Push(const T &t); 00082 00083 const T &Item(Int i) const 00084 { return(SELF[i]); }; 00085 T &Item(Int i) 00086 { return(SELF[i]); }; 00087 00088 InstArrayStats stats; 00089 }; 00090 00091 00092 // --- Inlines ---------------------------------------------------------------- 00093 00094 00095 #ifdef CL_INST_RW 00096 TMPLArray inline RWHelper<T> InstArray<T>::operator [] (Int i) 00097 { 00098 CheckRange(i, 0, items, "(InstArray::[]) index out of range"); 00099 00100 return(RWHelper<T>(stats, i, *((T*) (item + i * eltSize)))); 00101 } 00102 #else 00103 TMPLArray inline T &InstArray<T>::operator [] (Int i) 00104 { 00105 CheckRange(i, 0, items, "(InstArray::[]) index out of range"); 00106 00107 stats.Write(i); 00108 return(*((T*) (item + i * eltSize))); 00109 } 00110 #endif 00111 00112 TMPLArray inline const T &InstArray<T>::operator [] (Int i) const 00113 { 00114 CheckRange(i, 0, items, "(InstArray::[]) index out of range"); 00115 00116 stats.Read(i); 00117 return(*((T*) (item + i * eltSize))); 00118 } 00119 00120 TMPLArray inline T &InstArray<T>::Top() 00121 { 00122 stats.Write(i); 00123 return(*((T*) (item + (items - 1) * eltSize))); 00124 } 00125 00126 TMPLArray inline T &InstArray<T>::Last() 00127 { 00128 stats.Write(i); 00129 return(*((T*) (item + (items - 1) * eltSize))); 00130 } 00131 00132 TMPLArray inline const T &InstArray<T>::Top() const 00133 { 00134 stats.Read(i); 00135 return(*((T*) (item + (items - 1) * eltSize))); 00136 } 00137 00138 TMPLArray inline const T &InstArray<T>::Last() const 00139 { 00140 stats.Read(i); 00141 return(*((T*) (item + (items - 1) * eltSize))); 00142 } 00143 00144 TMPLArray inline Void InstArray<T>::Push(const T &t) 00145 { 00146 if (items >= allocated) 00147 Grow(); 00148 00149 stats.Write(i); 00150 memcpy(item + eltSize * items++, &t, eltSize); 00151 } 00152 00153 TMPLArray inline Void InstArray<T>::Append(const T &t) 00154 { 00155 if (items >= allocated) 00156 Grow(); 00157 00158 stats.Write(i); 00159 memcpy(item + eltSize * items++, &t, eltSize); 00160 } 00161 00162 #endif