gen.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 247 行
CC
247 行
/* * Copyright (c) 2002, 2003, 2004, 2005 * 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: Erik G. Hallnor * Steven K. Reinhardt *//** * @file * Definitions of the Generational replacement policy. */#include <string>#include "base/misc.hh"#include "mem/cache/tags/iic.hh"#include "mem/cache/tags/iic_repl/gen.hh"#include "params/GenRepl.hh"#include "sim/host.hh"using namespace std;GenRepl::GenRepl(const Params *p) // fix this, should be set by cache : Repl(p), num_pools(p->num_pools), fresh_res(p->fresh_res), pool_res(p->pool_res), num_entries(0), num_pool_entries(0), misses(0), pools(pools = new GenPool[num_pools+1]){}GenRepl::~GenRepl(){ delete [] pools;}unsigned longGenRepl::getRepl(){ unsigned long tmp; GenReplEntry *re; int i; int num_seen = 0; if (!(num_pool_entries>0)) { fatal("No blks available to replace"); } num_entries--; num_pool_entries--; for (i = 0; i < num_pools; i++) { while ((re = pools[i].pop())) { num_seen++; // Remove invalidated entries if (!re->valid) { delete re; continue; } if (iic->clearRef(re->tag_ptr)) { pools[(((i+1)== num_pools)? i :i+1)].push(re, misses); } else { tmp = re->tag_ptr; delete re; repl_pool.sample(i); return tmp; } } } fatal("No replacement found"); return 0xffffffff;}unsigned long *GenRepl::getNRepl(int n){ unsigned long *tmp; GenReplEntry *re; int i; if (!(num_pool_entries>(n-1))) { fatal("Not enough blks available to replace"); } num_entries -= n; num_pool_entries -= n; tmp = new unsigned long[n]; /* array of cache_blk pointers */ int blk_index = 0; for (i = 0; i < num_pools && blk_index < n; i++) { while (blk_index < n && (re = pools[i].pop())) { // Remove invalidated entries if (!re->valid) { delete re; continue; } if (iic->clearRef(re->tag_ptr)) { pools[(((i+1)== num_pools)? i :i+1)].push(re, misses); } else { tmp[blk_index] = re->tag_ptr; blk_index++; delete re; repl_pool.sample(i); } } } if (blk_index >= n) return tmp; /* search the fresh pool */ fatal("No N replacements found"); return NULL;}voidGenRepl::doAdvance(std::list<unsigned long> &demoted){ int i; int num_seen = 0; GenReplEntry *re; misses++; for (i=0; i<num_pools; i++) { while (misses-pools[i].oldest > pool_res && (re = pools[i].pop())!=NULL) { if (iic->clearRef(re->tag_ptr)) { pools[(((i+1)== num_pools)? i :i+1)].push(re, misses); /** @todo Not really demoted, but use it for now. */ demoted.push_back(re->tag_ptr); advance_pool.sample(i); } else { pools[(((i-1)<0)?i:i-1)].push(re, misses); demoted.push_back(re->tag_ptr); demote_pool.sample(i); } } num_seen += pools[i].size; } while (misses-pools[num_pools].oldest > fresh_res && (re = pools[num_pools].pop())!=NULL) { num_pool_entries++; if (iic->clearRef(re->tag_ptr)) { pools[num_pools/2].push(re, misses); /** @todo Not really demoted, but use it for now. */ demoted.push_back(re->tag_ptr); advance_pool.sample(num_pools); } else { pools[num_pools/2-1].push(re, misses); demoted.push_back(re->tag_ptr); demote_pool.sample(num_pools); } }}void*GenRepl::add(unsigned long tag_index){ GenReplEntry *re = new GenReplEntry; re->tag_ptr = tag_index; re->valid = true; pools[num_pools].push(re, misses); num_entries++; return (void*)re;}voidGenRepl::regStats(const string name){ using namespace Stats; /** GEN statistics */ repl_pool .init(0, 16, 1) .name(name + ".repl_pool_dist") .desc("Dist. of Repl. across pools") .flags(pdf) ; advance_pool .init(0, 16, 1) .name(name + ".advance_pool_dist") .desc("Dist. of Repl. across pools") .flags(pdf) ; demote_pool .init(0, 16, 1) .name(name + ".demote_pool_dist") .desc("Dist. of Repl. across pools") .flags(pdf) ;}intGenRepl::fixTag(void* _re, unsigned long old_index, unsigned long new_index){ GenReplEntry *re = (GenReplEntry*)_re; assert(re->valid); if (re->tag_ptr == old_index) { re->tag_ptr = new_index; return 1; } fatal("Repl entry: tag ptrs do not match"); return 0;}boolGenRepl::findTagPtr(unsigned long index){ for (int i = 0; i < num_pools + 1; ++i) { list<GenReplEntry*>::const_iterator iter = pools[i].entries.begin(); list<GenReplEntry*>::const_iterator end = pools[i].entries.end(); for (; iter != end; ++iter) { if ((*iter)->valid && (*iter)->tag_ptr == index) { return true; } } } return false;}GenRepl *GenReplParams::create(){ return new GenRepl(this);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?