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
00033 #include <pch.h>
00034
00035 #include "Sim/Memory/Cache/CacheSystem.h"
00036 #include "Sim/Memory/Cache/Cache.h"
00037 #include "Sim/Thread/Thread.h"
00038 #include "Sim/InorderList/InorderList.h"
00039 #include "Sim/Op/Op.h"
00040
00041
00042 using namespace std;
00043 using namespace Onikiri;
00044
00045 CacheSystem::CacheSystem() :
00046 m_firstLvDataCache(0),
00047 m_firstLvInsnCache(0),
00048 m_mode( SM_SIMULATION ),
00049 m_numRetiredStoreForwarding(0),
00050 m_numRetiredLoadAccess(0),
00051 m_numRetiredStoreAccess(0)
00052 {
00053 }
00054
00055 CacheSystem::~CacheSystem()
00056 {
00057 }
00058
00059 void CacheSystem::Initialize( InitPhase phase )
00060 {
00061 if(phase == INIT_PRE_CONNECTION){
00062
00063 LoadParam();
00064
00065 }
00066 else if( phase == INIT_POST_CONNECTION ){
00067
00068
00069 InitCacheHierarchy( &m_dataCacheHierarchy, &m_dataCacheHierarchyStr, m_firstLvDataCache );
00070 InitCacheHierarchy( &m_insnCacheHierarchy, &m_insnCacheHierarchyStr, m_firstLvInsnCache );
00071 m_loadAccessDispersion.resize( m_dataCacheHierarchy.size(), 0 );
00072 m_storeAccessDispersion.resize( m_dataCacheHierarchy.size(), 0 );
00073
00074 }
00075 }
00076
00077 void CacheSystem::Finalize()
00078 {
00079
00080 m_memoryAccessDispersion.clear();
00081 m_numRetiredMemoryAccess = 0;
00082 for( size_t i = 0; i < m_dataCacheHierarchy.size(); ++i ){
00083 m_memoryAccessDispersion.push_back(
00084 m_loadAccessDispersion[i] + m_storeAccessDispersion[i]
00085 );
00086 m_numRetiredMemoryAccess += m_memoryAccessDispersion[i];
00087 }
00088
00089
00090 CalculateCoverage( &m_loadAccessCoverage, m_loadAccessDispersion );
00091 CalculateCoverage( &m_storeAccessCoverage, m_storeAccessDispersion );
00092 CalculateCoverage( &m_memoryAccessCoverage, m_memoryAccessDispersion );
00093
00094
00095 s64 retiredInsns = 0;
00096 for( int i = 0; i < m_thread.GetSize(); i++ ){
00097 InorderList* ioList = m_thread[i]->GetInorderList();
00098 if( ioList ){
00099 retiredInsns += ioList->GetRetiredInsns();
00100 }
00101 }
00102
00103
00104 CalculateMissPerKiloInsns( &m_loadMPKI, m_loadAccessDispersion, retiredInsns );
00105 CalculateMissPerKiloInsns( &m_storeMPKI, m_storeAccessDispersion, retiredInsns );
00106 CalculateMissPerKiloInsns( &m_totalMPKI, m_memoryAccessDispersion, retiredInsns );
00107
00108 ReleaseParam();
00109 }
00110
00111
00112 void CacheSystem::CalculateCoverage(
00113 vector< double >* coverage,
00114 const vector< s64 >& dispersion
00115 ){
00116 s64 total = 0;
00117 for( vector< s64 >::const_iterator i = dispersion.begin(); i != dispersion.end(); ++i ){
00118 total += *i;
00119 }
00120
00121 s64 covered = 0;
00122 coverage->clear();
00123 for( vector< s64 >::const_iterator i = dispersion.begin(); i != dispersion.end(); ++i ){
00124 covered += *i;
00125 coverage->push_back( (double)covered / (double)total );
00126 }
00127 }
00128
00129
00130
00131 void CacheSystem::CalculateMissPerKiloInsns(
00132 std::vector< double >* mpki,
00133 const std::vector< s64 >& dispersion,
00134 s64 retiredInsns
00135 ){
00136 s64 misses = 0;
00137 for( vector< s64 >::const_iterator i = dispersion.begin(); i != dispersion.end(); ++i ){
00138 misses += *i;
00139 }
00140
00141 mpki->clear();
00142 for( vector< s64 >::const_iterator i = dispersion.begin(); i != dispersion.end(); ++i ){
00143 misses -= *i;
00144 mpki->push_back( 1000.0 * (double)misses / (double)retiredInsns );
00145 }
00146 }
00147
00148
00149 void CacheSystem::InitCacheHierarchy(
00150 vector< Cache* >* hierarchy,
00151 vector< string >* hierarchyStr,
00152 Cache* top
00153 ){
00154 hierarchy->clear();
00155 Cache* cache = top;
00156 for( int i = 0; cache; i++){
00157 hierarchy->push_back( cache );
00158 hierarchyStr->push_back( cache->GetName() );
00159 cache = cache->GetNextCache();
00160 }
00161 }
00162
00163 int CacheSystem::GetDataCacheLevel( Cache* cache )
00164 {
00165 for( size_t i = 0; i < m_dataCacheHierarchy.size(); ++i ){
00166 if( cache == m_dataCacheHierarchy[i] ){
00167 return (int)i;
00168 }
00169 }
00170
00171 ASSERT( "An unknow cache is passed." );
00172 return 0;
00173 }
00174
00175
00176 void CacheSystem::Commit( OpIterator op )
00177 {
00178 const OpClass& opClass = op->GetOpClass();
00179
00180 if( opClass.IsMem() ){
00181
00182 int level = 0;
00183 const CacheAccessResult& result = op->GetCacheAccessResult();
00184 if( result.cache == NULL ){
00185 if( opClass.IsLoad() ){
00186 m_numRetiredStoreForwarding++;
00187 }
00188 }
00189 else{
00190 level = GetDataCacheLevel( op->GetCacheAccessResult().cache );
00191 }
00192
00193 if( opClass.IsLoad() ){
00194 ASSERT( level < (int)m_loadAccessDispersion.size() );
00195 m_loadAccessDispersion[ level ]++;
00196 m_numRetiredLoadAccess++;
00197 }
00198 else{
00199 ASSERT( level < (int)m_storeAccessDispersion.size() );
00200 m_storeAccessDispersion[ level ]++;
00201 m_numRetiredStoreAccess++;
00202 }
00203 }
00204 }
00205
00206
00207
00208 void CacheSystem::ChangeSimulationMode( PhysicalResourceNode::SimulationMode mode )
00209 {
00210 m_mode = mode;
00211 }