📄 dash_prefetch.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * *//***************************************************************** * dash_prefetch.c * * Since the f77 compiler cannot issue prefetch opcodes, we * simulate the effect through the use of a shadow array. * The parameters that determine the mapping between shadow * and effective arrays are set by Tcl commands. This style of * prefetch was commonly used on dash. * * The Tcl interface is as follows * dashPrefetch enable * dashPrefetch disable * dashPrefetch (shared|exlcusive) baseAddr shadowAddr *****************************************************************/#include <string.h>#include "tcl_init.h"#include "cpu_interface.h"#include "hw_events.h"#include "sim_error.h"#include "memref.h"#include "cp0.h"#include "cpu.h"#include "cpu_stats.h"#define DASH_MAXENTRIES 512#define DASH_ENCODING 10000#define PF_NOTMAPPED (PF_NUMSTATS)static struct DashPrefetchState { VA shadowStart; VA shadowEnd; int arrayEntries; int except; VA arrayShadowStart[DASH_MAXENTRIES]; VA arrayStart[DASH_MAXENTRIES]; int64 issued[DASH_MAXENTRIES]; int64 stat[DASH_MAXENTRIES][PF_NUMSTATS+1]; SimTime nextOutput;} dashState;int dashPrefetchEnabled = 0;/***************************************************************** * prefetch command *****************************************************************/int DashPrefetch(int cpuNum, VA shadowAddr, void *vPtr, int size, int *retVal) { uint offset; int ret, id, typeSize; VA vAddr; PA pAddr=0; int exclusive; uint tlbFlavor; void *bdoorAddr = 0; if (simosCPUType != MIPSY) { return 0; } if (shadowAddr < dashState.shadowStart || shadowAddr >= dashState.shadowEnd) { return 0; /* no prefetch */ } /* * now, size should always be 4 */ ASSERT (size==4); typeSize = (*(int*)vPtr) / DASH_ENCODING; id = (*(int*)vPtr) % DASH_ENCODING; ASSERT (typeSize==4 || typeSize==8); exclusive = (id%2); id = id / 2; /* * debug stats */ if (CPUVec.CycleCount(cpuNum) >= dashState.nextOutput) { int i,j; CPUPrint("\n\n PREFETCH STATS at %lld cycles \n", CPUVec.CycleCount(cpuNum)); for (i=0;i<DASH_MAXENTRIES;i++) { if (dashState.issued[i]) { double x[PF_NUMSTATS+1]; for (j=0; j<PF_NUMSTATS+1; j++) { x[j] = 100.0 * dashState.stat[i][j] / dashState.issued[i]; } CPUPrint("PREFETCH id=%3d addr=0x%08x Issued=%10lld res=%6.2f%% merg=%6.2f%% fetch=%6.2f%% failure=%6.2f%% upg=%6.2f%% notmapped=%6.2f%%\n", i, dashState.arrayStart[i], dashState.issued[i], x[ PF_RESIDENT],x[PF_MERGE],x[PF_STALL], x[PF_FAILURE],x[PF_UPGRADE],x[PF_NOTMAPPED]); } } dashState.nextOutput += 32* 1024 * 1024 ; } ASSERT (id >= 0 && id < DASH_MAXENTRIES); if (!dashState.arrayStart[id]) { CPUError("Shadow entry %d not defined \n",id); } offset = shadowAddr - dashState.arrayShadowStart[id]; if (typeSize==8) { offset *=2; } vAddr = dashState.arrayStart[id] + offset; PREFETCH_ISSUE_EVENT(cpuNum,PE[cpuNum].PC,vAddr); dashState.issued[id]++; if (dashState.except) { tlbFlavor = TLB_DFETCH; } else { tlbFlavor = TLB_DFETCH | TLB_PREFETCH; } tlbFlavor = TLB_DFETCH | TLB_PREFETCH; ret = TranslateVirtual(&PE[cpuNum], vAddr, &pAddr, &tlbFlavor,&bdoorAddr); if (ret == SUCCESS) { if (exclusive) { if (MemRefPrefetch(cpuNum, vAddr, pAddr, 1)) { ret = PF_FAILURE; } else { ret = PF_SUCCESS; } } else { if (MemRefPrefetch(cpuNum, vAddr, pAddr, 0)) { ret = PF_FAILURE; } else { ret = PF_SUCCESS; } } if (interest(pAddr)) { DebugDetail('g', "dash-pf",cpuNum, "pAddr=0x%x vAddr=0x%x, exclusive=%d ret=%d \n", pAddr,vAddr,exclusive,ret); } dashState.stat[id][ret]++; if (ret == PF_FAILURE) { /* Think of a way to do this commonly to all cpus. */ STATS_INC(cpuNum, prefStats.prefFails, 1); PE[cpuNum].cpuStatus = cpu_stalled; PE[cpuNum].stalledInst = 0; STATS_SET(cpuNum, stallStart, CPUVec.CycleCount(cpuNum)); } else { ret = SUCCESS; } } else { if (!dashState.except) { ret = SUCCESS; } dashState.stat[id][PF_NOTMAPPED]++; PREFETCH_FAILED_TRANS(cpuNum,PE[cpuNum].PC,vAddr); } *retVal = ret; return 1; /* was a prefetch, ignore store instruction */}/***************************************************************** * Tcl interface to dash_prefetch *****************************************************************/int DashTclCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ int x[3]; if (simosCPUType != MIPSY) { Tcl_AppendResult(interp, "Can only use dashPrefetch in mipsy\n", NULL); return TCL_ERROR; } if (argc < 2) { Tcl_AppendResult(interp, "Use dashPrefetch [enable|disable|shadow|define|exception] \n", NULL); return TCL_ERROR; } if (!strcmp(argv[1], "enable")) { if (dashState.shadowStart < dashState.shadowEnd) { dashPrefetchEnabled = 1; return TCL_OK; } else { Tcl_AppendResult(interp, "dashPrefetch not initialized \n", NULL); return TCL_ERROR; } } if (!strcmp(argv[1],"shadow")) { if (argc<4) { Tcl_AppendResult(interp, "Use dashPrefetch shadow start size \n", NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &x[0]) != TCL_OK || Tcl_GetInt(interp, argv[3], &x[1]) != TCL_OK ) { Tcl_AppendResult(interp, "Use dashPrefetch shadow start end \n", NULL); return TCL_ERROR; } dashState.shadowStart = x[0]; dashState.shadowEnd = x[0] + x[1]; return TCL_OK; } if (!strcmp(argv[1],"disable")) { dashPrefetchEnabled = 0; return TCL_OK; } if (!strcmp(argv[1],"exception")) { dashState.except = 1; CPUWarning("DASH PREFETCH: excepting on TLB misses \n"); return TCL_OK; } if (!strcmp(argv[1],"define")) { if (argc < 5) { Tcl_AppendResult(interp, "Use dashPrefetch [define] id baseAddr shadowAddr \n", NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &x[0]) != TCL_OK || Tcl_GetInt(interp, argv[3], &x[1]) != TCL_OK || Tcl_GetInt(interp, argv[4], &x[2]) != TCL_OK ) { Tcl_AppendResult(interp, "Use dashPrefetch define id baseAddr shadowAddr \n", NULL); return TCL_ERROR; } if (x[0] < 0 || x[0] >DASH_MAXENTRIES) { Tcl_AppendResult(interp, "dashPrefetch id must in 0-255 range \n", NULL); return TCL_ERROR; } dashState.arrayStart[x[0]] = x[1]; dashState.arrayShadowStart[x[0]] = x[2]; return TCL_OK; } Tcl_AppendResult(interp, "Use dashPrefetch [enable|disable|define] \n", NULL); return TCL_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -