mem_dep_unit_impl.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 584 行 · 第 1/2 页

HH
584
字号
/* * Copyright (c) 2004, 2005, 2006 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Kevin T. Lim */#include <map>#include "cpu/o3/inst_queue.hh"#include "cpu/o3/mem_dep_unit.hh"template <class MemDepPred, class Impl>MemDepUnit<MemDepPred, Impl>::MemDepUnit()    : loadBarrier(false), loadBarrierSN(0), storeBarrier(false),      storeBarrierSN(0), iqPtr(NULL){}template <class MemDepPred, class Impl>MemDepUnit<MemDepPred, Impl>::MemDepUnit(Params *params)    : depPred(params->SSITSize, params->LFSTSize), loadBarrier(false),      loadBarrierSN(0), storeBarrier(false), storeBarrierSN(0), iqPtr(NULL){    DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n");}template <class MemDepPred, class Impl>MemDepUnit<MemDepPred, Impl>::~MemDepUnit(){    for (int tid=0; tid < Impl::MaxThreads; tid++) {        ListIt inst_list_it = instList[tid].begin();        MemDepHashIt hash_it;        while (!instList[tid].empty()) {            hash_it = memDepHash.find((*inst_list_it)->seqNum);            assert(hash_it != memDepHash.end());            memDepHash.erase(hash_it);            instList[tid].erase(inst_list_it++);        }    }#ifdef DEBUG    assert(MemDepEntry::memdep_count == 0);#endif}template <class MemDepPred, class Impl>std::stringMemDepUnit<MemDepPred, Impl>::name() const{    return "memdepunit";}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::init(Params *params, int tid){    DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid);    id = tid;    depPred.init(params->SSITSize, params->LFSTSize);}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::regStats(){    insertedLoads        .name(name() + ".memDep.insertedLoads")        .desc("Number of loads inserted to the mem dependence unit.");    insertedStores        .name(name() + ".memDep.insertedStores")        .desc("Number of stores inserted to the mem dependence unit.");    conflictingLoads        .name(name() + ".memDep.conflictingLoads")        .desc("Number of conflicting loads.");    conflictingStores        .name(name() + ".memDep.conflictingStores")        .desc("Number of conflicting stores.");}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::switchOut(){    assert(instList[0].empty());    assert(instsToReplay.empty());    assert(memDepHash.empty());    // Clear any state.    for (int i = 0; i < Impl::MaxThreads; ++i) {        instList[i].clear();    }    instsToReplay.clear();    memDepHash.clear();}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::takeOverFrom(){    // Be sure to reset all state.    loadBarrier = storeBarrier = false;    loadBarrierSN = storeBarrierSN = 0;    depPred.clear();}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::setIQ(InstructionQueue<Impl> *iq_ptr){    iqPtr = iq_ptr;}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst){    unsigned tid = inst->threadNumber;    MemDepEntryPtr inst_entry = new MemDepEntry(inst);    // Add the MemDepEntry to the hash.    memDepHash.insert(        std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));#ifdef DEBUG    MemDepEntry::memdep_insert++;#endif    instList[tid].push_back(inst);    inst_entry->listIt = --(instList[tid].end());    // Check any barriers and the dependence predictor for any    // producing memrefs/stores.    InstSeqNum producing_store;    if (inst->isLoad() && loadBarrier) {        DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n",                loadBarrierSN);        producing_store = loadBarrierSN;    } else if (inst->isStore() && storeBarrier) {        DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n",                storeBarrierSN);        producing_store = storeBarrierSN;    } else {        producing_store = depPred.checkInst(inst->readPC());    }    MemDepEntryPtr store_entry = NULL;    // If there is a producing store, try to find the entry.    if (producing_store != 0) {        DPRINTF(MemDepUnit, "Searching for producer\n");        MemDepHashIt hash_it = memDepHash.find(producing_store);        if (hash_it != memDepHash.end()) {            store_entry = (*hash_it).second;            DPRINTF(MemDepUnit, "Proucer found\n");        }    }    // If no store entry, then instruction can issue as soon as the registers    // are ready.    if (!store_entry) {        DPRINTF(MemDepUnit, "No dependency for inst PC "                "%#x [sn:%lli].\n", inst->readPC(), inst->seqNum);        inst_entry->memDepReady = true;        if (inst->readyToIssue()) {            inst_entry->regsReady = true;            moveToReady(inst_entry);        }    } else {        // Otherwise make the instruction dependent on the store/barrier.        DPRINTF(MemDepUnit, "Adding to dependency list; "                "inst PC %#x is dependent on [sn:%lli].\n",                inst->readPC(), producing_store);        if (inst->readyToIssue()) {            inst_entry->regsReady = true;        }        // Clear the bit saying this instruction can issue.        inst->clearCanIssue();        // Add this instruction to the list of dependents.        store_entry->dependInsts.push_back(inst_entry);        if (inst->isLoad()) {            ++conflictingLoads;        } else {            ++conflictingStores;        }    }    if (inst->isStore()) {        DPRINTF(MemDepUnit, "Inserting store PC %#x [sn:%lli].\n",                inst->readPC(), inst->seqNum);        depPred.insertStore(inst->readPC(), inst->seqNum, inst->threadNumber);        ++insertedStores;    } else if (inst->isLoad()) {        ++insertedLoads;    } else {        panic("Unknown type! (most likely a barrier).");    }}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst){    unsigned tid = inst->threadNumber;    MemDepEntryPtr inst_entry = new MemDepEntry(inst);    // Insert the MemDepEntry into the hash.    memDepHash.insert(        std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));#ifdef DEBUG    MemDepEntry::memdep_insert++;#endif    // Add the instruction to the list.    instList[tid].push_back(inst);    inst_entry->listIt = --(instList[tid].end());    // Might want to turn this part into an inline function or something.    // It's shared between both insert functions.    if (inst->isStore()) {        DPRINTF(MemDepUnit, "Inserting store PC %#x [sn:%lli].\n",                inst->readPC(), inst->seqNum);        depPred.insertStore(inst->readPC(), inst->seqNum, inst->threadNumber);        ++insertedStores;    } else if (inst->isLoad()) {        ++insertedLoads;    } else {        panic("Unknown type! (most likely a barrier).");    }}template <class MemDepPred, class Impl>voidMemDepUnit<MemDepPred, Impl>::insertBarrier(DynInstPtr &barr_inst){    InstSeqNum barr_sn = barr_inst->seqNum;    // Memory barriers block loads and stores, write barriers only stores.    if (barr_inst->isMemBarrier()) {        loadBarrier = true;        loadBarrierSN = barr_sn;        storeBarrier = true;        storeBarrierSN = barr_sn;        DPRINTF(MemDepUnit, "Inserted a memory barrier\n");    } else if (barr_inst->isWriteBarrier()) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?