src/Sim/Memory/Prefetcher/StridePrefetcher.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 
00034 #include "Sim/Memory/Prefetcher/StridePrefetcher.h"
00035 #include "Sim/Op/Op.h"
00036 
00037 using namespace Onikiri;
00038 
00039 //#define STRIDE_PREFETCHER_DEBUG 1
00040 
00041 String StridePrefetcher::Stream::ToString() const
00042 {
00043     String str;
00044 
00045     // Status
00046     str += "status: ";
00047     switch( status ){
00048     default:
00049     case SS_INVALID:
00050         str += "INVALID ";
00051         break;
00052     case SS_ALLOCATED:
00053         str += "ALLOCATED ";
00054         break;
00055     }
00056 
00057     // Window
00058     str += "  pc: ";
00059     str += pc.ToString();
00060     str += "  addr: ";
00061     str += addr.ToString();
00062     str += "  stride: ";
00063     str += String().format( "%llx", stride );
00064     
00065     // Count
00066     str += "  count: ";
00067     str += String().format( "%d", count );
00068     str += "  conf: ";
00069     str += String().format( "%d", (int)confidence );
00070     return str;
00071 
00072 }
00073 
00074 
00075 StridePrefetcher::StridePrefetcher()
00076 {
00077     m_distance = 0;
00078     m_degree = 0;
00079     m_streamTableSize = 0;
00080 
00081     m_numPrefetchingStream = 0;
00082     m_numAvgPrefetchStreamLength = 0.0;
00083 }
00084 
00085 
00086 StridePrefetcher::~StridePrefetcher()
00087 {
00088     if( m_numPrefetchingStream ){
00089         m_numAvgPrefetchStreamLength = 
00090             (double)m_numPrefetch / (double)m_numPrefetchingStream;
00091     }
00092 
00093     ReleaseParam();
00094 }
00095 
00096 
00097 // --- PhysicalResourceNode
00098 void StridePrefetcher::Initialize(InitPhase phase)
00099 {
00100     PrefetcherBase::Initialize( phase );
00101 
00102     if(phase == INIT_PRE_CONNECTION){
00103         
00104         LoadParam();
00105         m_streamTable.construct( m_streamTableSize );
00106     }
00107     else if(phase == INIT_POST_CONNECTION){
00108     
00109     }
00110 }
00111 
00112 
00113 // This method is called by any cache accesses occurred in a connected cache.
00114 void StridePrefetcher::OnCacheAccess( 
00115     Cache* cache, 
00116     const CacheAccess& access,
00117     bool hit
00118 ){
00119     if( !m_enabled ){
00120         return;
00121     }
00122 
00123     OpIterator op = access.op;
00124     if( op.IsNull() ){
00125         return;
00126     }
00127 
00128     Addr pc = op->GetPC();
00129     Addr missAddr = op->GetMemAccess().address;//access.address;
00130     //missAddr.address = MaskLineOffset( missAddr.address );
00131 
00132 #ifdef STRIDE_PREFETCHER_DEBUG
00133     g_env.Print(
00134         String( "access\t" ) + 
00135         "pc: " + pc.ToString() + 
00136         "  addr: " + missAddr.ToString() + 
00137         ( hit ? " hit" : " miss" ) + 
00138         "\n" 
00139     );
00140 #endif
00141 
00142 
00143 //  bool streamHit = false;
00144 
00145     for( size_t i = 0; i < m_streamTable.size(); i++ ){
00146         Stream* stream = &m_streamTable[i];
00147         if( stream->status == SS_INVALID )
00148             continue;
00149         
00150         if( stream->pc != pc )
00151             continue;
00152 
00153         m_streamTable.touch( i );
00154 //      streamHit = true;
00155         stream->count++;
00156 
00157 #ifdef STRIDE_PREFETCHER_DEBUG
00158         g_env.Print( String( "  stream\t" ) + stream->ToString() + "\n" );
00159 #endif
00160 
00161         if( stream->addr.address + stream->stride == missAddr.address ){
00162 
00163             if( stream->confidence.above_threshold() ){
00164 
00165                 for( int d = 0; d < m_degree; d++ ){
00166                     CacheAccess prefetch;
00167                     prefetch.op = op;
00168                     prefetch.type = CacheAccess::OT_PREFETCH;
00169 
00170                     // Prefetch 'end' point of a window.
00171                     prefetch.address = missAddr;
00172                     prefetch.address.address += 
00173                         stream->stride * (m_distance + d);
00174 
00175                     PrefetcherBase::Prefetch( prefetch );
00176                     //m_prefetchTarget->Read( prefetch, NULL );
00177 
00178 #ifdef STRIDE_PREFETCHER_DEBUG
00179                     g_env.Print( 
00180                         String( "  prefetch\t" ) + 
00181                         prefetch.address.ToString() + 
00182                         "\n" 
00183                     );
00184 #endif
00185                 }
00186 
00187                 IncrementPrefetchNum();
00188                 if( stream->status != SS_PREFETCHING ){
00189                     m_numPrefetchingStream++;
00190                 }
00191                 stream->status = SS_PREFETCHING;    
00192             }
00193 
00194             stream->confidence.inc();
00195             stream->streamLength++;
00196         }
00197         else{
00198             stream->confidence.dec();
00199         }
00200 
00201         stream->stride = 
00202             (s64)missAddr.address - (s64)stream->addr.address;
00203         stream->addr.address = missAddr.address;
00204 
00205         if( stream->stride == 0 ){
00206             stream->status = SS_INVALID;
00207         }
00208         return;
00209     }
00210 
00211     if( hit )
00212         return;
00213 
00214     // Allocate a new stride stream.
00215     Stream stream;
00216     stream.Reset();
00217     stream.pc   = pc;
00218     stream.addr = missAddr;
00219     stream.orig = missAddr;
00220     stream.stride = m_lineSize;
00221     stream.status = SS_ALLOCATED;
00222 
00223     int target = (int)m_streamTable.replacement_target();
00224     m_streamTable[ target ] = stream;
00225     m_streamTable.touch( target );
00226 
00227 #ifdef STRIDE_PREFETCHER_DEBUG
00228     g_env.Print( 
00229         String( "  alloc\t" ) + 
00230         missAddr.ToString() + " " + 
00231         stream.ToString() + "\n" 
00232     );
00233 #endif
00234 
00235 //  m_numAllocatedStream++;
00236 }
00237 

Onikiri2に対してTue Jun 18 14:34:24 2013に生成されました。  doxygen 1.4.7