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
00030
00031
00032 #ifndef __STRIDEPREDICTOR_H__
00033 #define __STRIDEPREDICTOR_H__
00034
00035 #include <list>
00036 #include <vector>
00037 #include <algorithm>
00038 using namespace std;
00039
00040 namespace Onikiri {
00041 template <typename T>
00042 class StridePred
00043 {
00044 protected:
00045
00046 struct Stream
00047 {
00048 T next;
00049 T diff;
00050 unsigned int conf;
00051 unsigned int time;
00052 };
00053
00054
00055 class SelectStream
00056 {
00057 public:
00058 bool operator()(Stream left,Stream right) const
00059 {
00060 if(left.conf == right.conf)
00061 return left.time < right.time;
00062 else
00063 return left.conf > right.conf;
00064 }
00065 };
00066
00067 class SelectDeleteEntry
00068 {
00069 public:
00070 bool operator()(Stream left,Stream right) const
00071 {
00072 if(left.time == right.time)
00073 return left.conf < right.conf;
00074 else
00075 return left.time > right.time;
00076 }
00077 };
00078
00079 unsigned int m_historySize;
00080 list<T> m_historyTable;
00081 unsigned int m_streamSize;
00082 vector<Stream> m_streamTable;
00083
00084 void Analyze(T t)
00085 {
00086 vector<Stream>::iterator sitr = m_streamTable.begin();
00087 while(sitr != m_streamTable.end())
00088 {
00089 (*sitr).time++;
00090 if((*sitr).next == t)
00091 {
00092 (*sitr).next += (*sitr).diff;
00093 (*sitr).conf++;
00094 (*sitr).time = 0;
00095 }
00096 sitr++;
00097 }
00098 list<T>::iterator titr = m_historyTable.begin();
00099 sort(m_streamTable.begin(),m_streamTable.end(),SelectDeleteEntry());
00100 while(titr != m_historyTable.end())
00101 {
00102 Stream s;
00103 s.time = 0;
00104 s.conf = 1;
00105 s.diff = t - (*titr);
00106 s.next = t + s.diff;
00107 if(CheckDuplication(s))
00108 {
00109 if(m_streamTable.size() == m_streamSize)
00110 m_streamTable.erase(m_streamTable.begin());
00111 m_streamTable.push_back(s);
00112 }
00113 titr++;
00114 }
00115 }
00116
00117 bool CheckDuplication(Stream s)
00118 {
00119 vector<Stream>::iterator itr = m_streamTable.begin();
00120 while(itr != m_streamTable.end())
00121 {
00122 if(s.next == (*itr).next && s.diff == (*itr).diff)
00123 return false;
00124 itr++;
00125 }
00126 return true;
00127 }
00128 public:
00129 StridePred(int historySize, int streamSize)
00130 {
00131 Initialize(historySize,streamSize);
00132 }
00133 ~StridePred(){}
00134
00135 void Initialize(int historySize, int streamSize)
00136 {
00137 m_historySize = historySize;
00138 m_streamSize = streamSize;
00139 m_historyTable.clear();
00140 m_streamTable.clear();
00141 }
00142
00143 void Update(T t)
00144 {
00145 Analyze(t);
00146 m_historyTable.push_back(t);
00147 if(m_historySize < m_historyTable.size())
00148 m_historyTable.pop_front();
00149 }
00150
00151 void Predict(T* pt, int num)
00152 {
00153 sort(m_streamTable.begin(),m_streamTable.end(),SelectStream());
00154 vector<Stream>::iterator itr = m_streamTable.begin();
00155 for(int i = 0;i < num && itr != m_streamTable.end();i++,itr++)
00156 {
00157 pt[i] = (*itr).next;
00158 }
00159 }
00160
00161
00162 void Update(T* pt, int num)
00163 {
00164 for(int i = 0;i < num;i++)
00165 Update(pt[i]);
00166 }
00167
00168 void PrintStream()
00169 {
00170 sort(m_streamTable.begin(),m_streamTable.end(),SelectStream());
00171 vector<Stream>::iterator itr = m_streamTable.begin();
00172 while(itr != m_streamTable.end())
00173 PrintStream(*(itr++));
00174 }
00175 void PrintStream(Stream s)
00176 {
00177 cout << "next:" << s.next << " diff" << s.diff << " conf:" << s.conf << " time:" << s.time << "\n";
00178 for(int i = s.conf + 1;i > 0;i--)
00179 {
00180 cout << s.next - i*s.diff << " ";
00181 }
00182
00183 cout << "\n";
00184 }
00185 };
00186 };
00187
00188 #endif // __STRIDEPREDICTOR_H__