dep_graph.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 273 行
HH
273 行
/* * Copyright (c) 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 */#ifndef __CPU_O3_DEP_GRAPH_HH__#define __CPU_O3_DEP_GRAPH_HH__#include "cpu/o3/comm.hh"/** Node in a linked list. */template <class DynInstPtr>class DependencyEntry{ public: DependencyEntry() : inst(NULL), next(NULL) { } DynInstPtr inst; //Might want to include data about what arch. register the //dependence is waiting on. DependencyEntry<DynInstPtr> *next;};/** Array of linked list that maintains the dependencies between * producing instructions and consuming instructions. Each linked * list represents a single physical register, having the future * producer of the register's value, and all consumers waiting on that * value on the list. The head node of each linked list represents * the producing instruction of that register. Instructions are put * on the list upon reaching the IQ, and are removed from the list * either when the producer completes, or the instruction is squashed.*/template <class DynInstPtr>class DependencyGraph{ public: typedef DependencyEntry<DynInstPtr> DepEntry; /** Default construction. Must call resize() prior to use. */ DependencyGraph() : numEntries(0), memAllocCounter(0), nodesTraversed(0), nodesRemoved(0) { } ~DependencyGraph(); /** Resize the dependency graph to have num_entries registers. */ void resize(int num_entries); /** Clears all of the linked lists. */ void reset(); /** Inserts an instruction to be dependent on the given index. */ void insert(PhysRegIndex idx, DynInstPtr &new_inst); /** Sets the producing instruction of a given register. */ void setInst(PhysRegIndex idx, DynInstPtr &new_inst) { dependGraph[idx].inst = new_inst; } /** Clears the producing instruction. */ void clearInst(PhysRegIndex idx) { dependGraph[idx].inst = NULL; } /** Removes an instruction from a single linked list. */ void remove(PhysRegIndex idx, DynInstPtr &inst_to_remove); /** Removes and returns the newest dependent of a specific register. */ DynInstPtr pop(PhysRegIndex idx); /** Checks if there are any dependents on a specific register. */ bool empty(PhysRegIndex idx) { return !dependGraph[idx].next; } /** Debugging function to dump out the dependency graph. */ void dump(); private: /** Array of linked lists. Each linked list is a list of all the * instructions that depend upon a given register. The actual * register's index is used to index into the graph; ie all * instructions in flight that are dependent upon r34 will be * in the linked list of dependGraph[34]. */ DepEntry *dependGraph; /** Number of linked lists; identical to the number of registers. */ int numEntries; // Debug variable, remove when done testing. unsigned memAllocCounter; public: // Debug variable, remove when done testing. uint64_t nodesTraversed; // Debug variable, remove when done testing. uint64_t nodesRemoved;};template <class DynInstPtr>DependencyGraph<DynInstPtr>::~DependencyGraph(){ delete [] dependGraph;}template <class DynInstPtr>voidDependencyGraph<DynInstPtr>::resize(int num_entries){ numEntries = num_entries; dependGraph = new DepEntry[numEntries];}template <class DynInstPtr>voidDependencyGraph<DynInstPtr>::reset(){ // Clear the dependency graph DepEntry *curr; DepEntry *prev; for (int i = 0; i < numEntries; ++i) { curr = dependGraph[i].next; while (curr) { memAllocCounter--; prev = curr; curr = prev->next; prev->inst = NULL; delete prev; } if (dependGraph[i].inst) { dependGraph[i].inst = NULL; } dependGraph[i].next = NULL; }}template <class DynInstPtr>voidDependencyGraph<DynInstPtr>::insert(PhysRegIndex idx, DynInstPtr &new_inst){ //Add this new, dependent instruction at the head of the dependency //chain. // First create the entry that will be added to the head of the // dependency chain. DepEntry *new_entry = new DepEntry; new_entry->next = dependGraph[idx].next; new_entry->inst = new_inst; // Then actually add it to the chain. dependGraph[idx].next = new_entry; ++memAllocCounter;}template <class DynInstPtr>voidDependencyGraph<DynInstPtr>::remove(PhysRegIndex idx, DynInstPtr &inst_to_remove){ DepEntry *prev = &dependGraph[idx]; DepEntry *curr = dependGraph[idx].next; // Make sure curr isn't NULL. Because this instruction is being // removed from a dependency list, it must have been placed there at // an earlier time. The dependency chain should not be empty, // unless the instruction dependent upon it is already ready. if (curr == NULL) { return; } nodesRemoved++; // Find the instruction to remove within the dependency linked list. while (curr->inst != inst_to_remove) { prev = curr; curr = curr->next; nodesTraversed++; assert(curr != NULL); } // Now remove this instruction from the list. prev->next = curr->next; --memAllocCounter; // Could push this off to the destructor of DependencyEntry curr->inst = NULL; delete curr;}template <class DynInstPtr>DynInstPtrDependencyGraph<DynInstPtr>::pop(PhysRegIndex idx){ DepEntry *node; node = dependGraph[idx].next; DynInstPtr inst = NULL; if (node) { inst = node->inst; dependGraph[idx].next = node->next; node->inst = NULL; memAllocCounter--; delete node; } return inst;}template <class DynInstPtr>voidDependencyGraph<DynInstPtr>::dump(){ DepEntry *curr; for (int i = 0; i < numEntries; ++i) { curr = &dependGraph[i]; if (curr->inst) { cprintf("dependGraph[%i]: producer: %#x [sn:%lli] consumer: ", i, curr->inst->readPC(), curr->inst->seqNum); } else { cprintf("dependGraph[%i]: No producer. consumer: ", i); } while (curr->next != NULL) { curr = curr->next; cprintf("%#x [sn:%lli] ", curr->inst->readPC(), curr->inst->seqNum); } cprintf("\n"); } cprintf("memAllocCounter: %i\n", memAllocCounter);}#endif // __CPU_O3_DEP_GRAPH_HH__
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?