src/Sim/Predictor/DepPred/MemDepPred/StoreSet.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/Predictor/DepPred/MemDepPred/StoreSet.h"
00035 #include "Sim/Op/Op.h"
00036 
00037 using namespace Onikiri;
00038 using namespace boost;
00039 
00040 StoreSet::StoreSet() :
00041     m_core(0),
00042     m_storeIDTable              (0),
00043     m_producerTable             (0),
00044     m_numStoreIDTableEntryBits  (0),
00045     m_numStoreIDTableWays       (0),
00046     m_numProducerTableEntryBits (0),
00047     m_numProducerTableWays      (0),
00048     m_numStoreIDTableEntries    (0),
00049     m_numProducerTableEntries   (0),
00050     m_numAccessOrderViolated    (0)
00051 {
00052 }
00053 
00054 StoreSet::~StoreSet()
00055 {
00056     if( m_storeIDTable ) {
00057         delete m_storeIDTable;
00058     }
00059     if( m_producerTable ) {
00060         delete m_producerTable;
00061     }
00062 
00063     // entry count
00064     m_numStoreIDTableEntries    = (1 << m_numStoreIDTableEntryBits);
00065     m_numProducerTableEntries   = (1 << m_numProducerTableEntryBits);
00066     ReleaseParam();
00067 }
00068 
00069 void StoreSet::Initialize(InitPhase phase)
00070 {
00071     if( phase == INIT_PRE_CONNECTION ) {
00072         LoadParam();
00073     } else if( phase == INIT_POST_CONNECTION ) {
00074         m_storeIDTable = 
00075             new StoreIDTableType( 
00076                 HasherType( m_numStoreIDTableEntryBits, WORD_BITS ),
00077                 m_numStoreIDTableWays 
00078             );
00079         m_producerTable = 
00080             new ProducerTableType( 
00081                 HasherType( m_numProducerTableEntryBits, WORD_BITS ), 
00082                 m_numProducerTableWays 
00083             );
00084         m_allocatedStoreIDTable.Resize(*m_core->GetOpArray());
00085     }
00086 
00087 }
00088 
00089 void StoreSet::Resolve(OpIterator op)
00090 {
00091     if( !op->GetOpClass().IsMem() ) {
00092         return;
00093     }
00094 
00095     StoreSetID storeSetID = GetStoreSetID(op);
00096     if( storeSetID.address != INVALID_STORESET_ID) {
00097         OpIterator producer = GetProducerStore(storeSetID);
00098         if( !producer.IsNull() ) {
00099             ResolveMemDependency(op, producer);
00100         }
00101     }
00102 }
00103 
00104 // allocate memory dependency to stores which caused Access Order Violation in the past 
00105 void StoreSet::Allocate(OpIterator op)
00106 {
00107     // allocate only stores
00108     if( !op->GetOpClass().IsStore() ) {
00109         return;
00110     }
00111 
00112     StoreSetID storeSetID = GetStoreSetID(op);
00113     if( storeSetID.address != INVALID_STORESET_ID) {
00114         // update tables and allocate dependency
00115         UpdateProducerTable(storeSetID, op);
00116         AllocateMemDependency(op);
00117     }
00118 }
00119 
00120 void StoreSet::Commit(OpIterator op)
00121 {
00122     if( op->GetOpClass().IsMem() ) {
00123         Deallocate(op);
00124     }
00125 }
00126 
00127 void StoreSet::Flush(OpIterator op)
00128 {
00129     if( op->GetStatus() == OpStatus::OS_FETCH ){
00130         return;
00131     }
00132     if( op->GetOpClass().IsMem() ) {
00133         Deallocate(op);
00134     }
00135 }
00136 
00137 // update Store Set on the event of Access Order Violation
00138 void StoreSet::OrderConflicted(OpIterator producer, OpIterator consumer)
00139 {
00140     ASSERT(producer->GetOpClass().IsStore(), "producerOp is not store(%s)", producer->ToString(6).c_str());
00141     ASSERT(consumer->GetOpClass().IsMem(), "consumerOp is not load/store(%s)", consumer->ToString(6).c_str());
00142 
00143     m_numAccessOrderViolated++;
00144 
00145     StoreSetID producerID = GetStoreSetID(producer);
00146     StoreSetID consumerID = GetStoreSetID(consumer);
00147 
00148     // update method varies depending on which Store Set IDs are present
00149     if( producerID.address == INVALID_STORESET_ID && consumerID.address == INVALID_STORESET_ID ) {
00150         // no entry exists, so create a new entry
00151         StoreSetID id = GetNewID(producer);
00152         UpdateStoreSetIDTable(producer, id);
00153         UpdateStoreSetIDTable(consumer, id);
00154     } else if( producerID.address != INVALID_STORESET_ID && consumerID.address == INVALID_STORESET_ID ) {
00155         // producer ID exists, so set consumer ID to the same number
00156         UpdateStoreSetIDTable(consumer, producerID);
00157     } else if( producerID.address == INVALID_STORESET_ID && consumerID.address != INVALID_STORESET_ID ) {
00158         // consumer ID exists, so set producer ID to the same number
00159         UpdateStoreSetIDTable(producer, consumerID);
00160     } else {
00161         if( producerID == consumerID ) {
00162             // same conflict occurred in the past
00163             return;
00164         }
00165 
00166         // if both IDs exist, compare them and set the bigger one to the smaller one
00167         if( producerID.address < consumerID.address ) {
00168             UpdateStoreSetIDTable(consumer, producerID);
00169         } else {
00170             // producer's table entry go out of use, so invalidate the entry
00171             ReleaseProducerTable(producer);
00172             UpdateStoreSetIDTable(producer, consumerID);
00173         }
00174     }
00175 }
00176 
00177 bool StoreSet::CanAllocate(OpIterator* infoArray, int numOp)
00178 {
00179     return true;
00180 }
00181 
00182 void StoreSet::AllocateMemDependency(OpIterator op)
00183 {
00184     if( op->GetDstMem(0) == NULL ) {
00185         MemDependencyPtr tmpMem(
00186             m_memDepPool.construct(m_core->GetNumScheduler()) );
00187         tmpMem->Clear();
00188         op->SetDstMem(0, tmpMem);
00189     }
00190 }
00191 
00192 void StoreSet::ResolveMemDependency(OpIterator consumer, OpIterator producer)
00193 {
00194     ASSERT(producer->GetOpClass().IsStore(), "op is not store(%s)", producer->ToString(6).c_str());
00195     consumer->SetSrcMem(0, producer->GetDstMem(0));
00196 }
00197 
00198 void StoreSet::Deallocate(const OpIterator op)
00199 {
00200     StoreSetID id = GetStoreSetID(op);
00201     if( id.address ) {
00202         ReleaseProducerTable(op);
00203         m_allocatedStoreIDTable[op] = StoreSetID();
00204     }
00205 }
00206 
00207 // update store set ID table and set op's ID
00208 void StoreSet::UpdateStoreSetIDTable(OpIterator op, StoreSetID id)
00209 {
00210     m_storeIDTable->write( op->GetPC(), id );
00211 }
00212 
00213 // assign a producer op to Store Set ID
00214 void StoreSet::UpdateProducerTable(StoreSetID id, OpIterator op)
00215 {
00216     m_producerTable->write(id, op);
00217     m_allocatedStoreIDTable[op] = id;
00218 }
00219 
00220 // deallocate producer table's entry if the op is the latest producer of the allocated Store Set ID
00221 // (do nothing when new producer of the same ID was fetched)
00222 void StoreSet::ReleaseProducerTable(OpIterator op)
00223 {
00224     StoreSetID allocatedID = m_allocatedStoreIDTable[op];
00225 
00226     OpIterator lastProducer;
00227     bool producerFound = m_producerTable->read( allocatedID, &lastProducer ) != m_producerTable->end();
00228     if( producerFound ) {
00229         if( !lastProducer.IsNull() && lastProducer->GetGlobalSerialID() == op->GetGlobalSerialID() ){
00230             // the op is the latest producer of the allocatedID, so invalidate the table entry
00231             m_producerTable->write( allocatedID, OpIterator(0) );
00232         }
00233     }
00234 }
00235 
00236 // reserve producer table entry with op's PC(StoreSetID), and return new ID
00237 StoreSet::StoreSetID StoreSet::GetNewID(const OpIterator op)
00238 {
00239     StoreSetID id = op->GetPC();
00240     m_producerTable->write( op->GetPC(), OpIterator(0) );
00241     return id;
00242 }
00243 
00244 StoreSet::StoreSetID StoreSet::GetStoreSetID(const OpIterator op)
00245 {
00246     StoreSetID id( op->GetPID(), op->GetTID(), INVALID_STORESET_ID );
00247     m_storeIDTable->read( op->GetPC(), &id );
00248     return id;
00249 }
00250 
00251 OpIterator StoreSet::GetProducerStore(const StoreSetID id)
00252 {
00253     OpIterator producer;
00254     bool producerFound = m_producerTable->read( id, &producer ) != m_producerTable->end();
00255     if( producerFound && !producer.IsNull()) {
00256         return producer;
00257     } else {
00258         return OpIterator(0);
00259     }
00260 }

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