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