⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 false_sharing.c

📁 一个用在mips体系结构中的操作系统
💻 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.  * *//*********************************************************************** * false_sharing.c * Cache interface that determines true and false sharing. *  * $Author: bosch $ * $Date: 1998/02/10 00:28:55 $ * * XXX bug: scales with TOTAL_CPUS, which is bad * XXX      for multiple machines (although theoretically correct) * XXX bug: sparse address space not really supported ***********************************************************************/#include <stdlib.h>#include "string.h"#include "sim_error.h"#include "cpu_interface.h"#include "simutil.h"#include "machine_params.h"#include "false_sharing.h"#include "memstat.h"#include "statrecord.h"#include "tcl_init.h"#include "arch_specifics.h"FalseSharingBV *falseSharingMaskEntries[MAX_MACHINES];uint falseSharingMask;bool falseSharing;static FalseSharingEntry *falseSharingAccessed[MAX_MACHINES][SIM_MAXCPUS];static FalseSharingBV *falseSharingModifyWords;static MA startMA;static MA endMA;static struct {   StatRecordFieldDesc falseSharing[NUM_CATEGS];   StatRecordFieldDesc trueSharing[NUM_CATEGS];   StatRecordFieldDesc falseSharingStall[NUM_CATEGS];   StatRecordFieldDesc trueSharingStall[NUM_CATEGS];} falseSharingBucket;#define PADDR_TO_INDEX(_pa,_way) \ (((_pa>>log2SCACHE_LINE_SIZE) & (SCACHE_INDEX-1))*SCACHE_ASSOC + _way)#ifdef TRACK_FALSE_SHARINGint FalseSharing = 1;#elseint FalseSharing = 0;#endifextern int memstatOption;/***************************************************************** * FalseSharingInit *****************************************************************/void FalseSharingEarlyInit(void){   if (FalseSharing) {       if (memstatOption == 0) {         CPUWarning("\n\nFALSE SHARING: requires MemStat enabled (Level != None)\n\n");         return;      }      MemStatInitCategoryFields(falseSharingBucket.trueSharing, "trueSharing",                                 STATRECORD_DATA|STATRECORD_INSTRUCTION);      MemStatInitCategoryFields(falseSharingBucket.falseSharing, "falseSharing",                                 STATRECORD_DATA|STATRECORD_INSTRUCTION);      MemStatInitCategoryFields(falseSharingBucket.trueSharingStall, "trueShStall",                                 STATRECORD_DATA|STATRECORD_INSTRUCTION);      MemStatInitCategoryFields(falseSharingBucket.falseSharingStall, "falseShStall",                                 STATRECORD_DATA|STATRECORD_INSTRUCTION);      falseSharing = 1;   }}    void FalseSharingLateInit(void){   int machine;   int i;   int scacheLine   = SCACHE_LINE_SIZE;   int scacheSize   = SCACHE_SIZE;   int shift;   long totalMemSize = 0;   if (!falseSharing) {       return;     }   CPUWarning("FALSE SHARING: initialized\n");   falseSharingMask = scacheLine -1;      if (scacheLine > 4* 8 * sizeof(FalseSharingBV)) {      shift = GetLog2(scacheLine / (8 * sizeof(FalseSharingBV)));   } else {      shift = 2; /* word granularity */   }   ASSERT(TOTAL_CPUS && NUM_MACHINES);   for (machine = 0; machine < NUM_MACHINES; machine++) {      ASSERT(MEM_SIZE(machine));      totalMemSize += MEM_SIZE(machine);            falseSharingMaskEntries[machine] =          (FalseSharingBV *) ZALLOC_PERM(scacheLine* sizeof(FalseSharingBV),                                        "FalseSharing");      for (i=0; i<scacheLine; i++) {         uint j = (i>>shift);         ASSERT( j < 8 * sizeof(FalseSharingBV) );         falseSharingMaskEntries[machine][i] = 1<<j;      }             for (i=0; i<NUM_CPUS(machine); i++) {          int j;         falseSharingAccessed[machine][i] =             (FalseSharingEntry *) ZALLOC_PERM(sizeof(FalseSharingEntry)                                               * scacheSize / scacheLine ,"FalseSharing");         for(j=0;j< scacheSize / scacheLine; j++) {            falseSharingAccessed[machine][i][j].categ = -1;         }      }   }   falseSharingModifyWords = (FalseSharingBV *)      ZALLOC_PERM(sizeof(FalseSharingBV)*                  (totalMemSize/scacheLine) *                  TOTAL_CPUS,                  "FalseSharing");   ASSERT(falseSharingModifyWords);   startMA = PHYS_TO_MEMADDR(0,0);   endMA   = startMA + totalMemSize;   ASSERT(startMA);}/***************************************************************** * SCacheLineToFalseSharing *****************************************************************/FalseSharingEntry *SCacheLineToFalseSharing(int cpuNum, PA pAddr, int way) {   uint index = PADDR_TO_INDEX(pAddr,way);   if (!falseSharing) {       return 0;   } else {       return (falseSharingAccessed[M_FROM_CPU(cpuNum)]              [MCPU_FROM_CPU(cpuNum)]) + index ;   }}/***************************************************************** * FalseSharingDefine *****************************************************************/void FalseSharingDefine(int cpuNum, PA pAddr, int way, VA PC, VA vAddr, int stall){   uint index;   FalseSharingEntry *e;   if( !falseSharing ) { return; }   index = PADDR_TO_INDEX(pAddr,way);   if( interest(pAddr)) {      LogEntry("def", cpuNum,"pA=0x%08x index=0x%06x way=%i \n",pAddr,index,way);   }   e = (falseSharingAccessed[M_FROM_CPU(cpuNum)]        [MCPU_FROM_CPU(cpuNum)])+index;   ASSERT (!e->valid);#ifndef SIM_ALPHA   ASSERT (vAddr);#endif   e->valid = 1;   e->PC = PC;   e->vAddr = vAddr;   e->pAddr = pAddr;   e->stall = stall;   e->snap = StatRecordAllocSnapshot(cpuNum);   e->accessedWords = 0;  /* clear bit vector */   e->categ = -1;}/***************************************************************** * FalseSharingDefineOffset *****************************************************************/void FalseSharingDefineOffset(int cpuNum, PA pAddr,int way, int categ){   uint index;   FalseSharingEntry *e;   if( !falseSharing ) { return; }   index = PADDR_TO_INDEX(pAddr,way);   e = (falseSharingAccessed[M_FROM_CPU(cpuNum)]        [MCPU_FROM_CPU(cpuNum)])+index;   ASSERT (e->valid);   ASSERT( e->categ < 0 );   ASSERT( categ >= 0 && categ < NUM_CATEGS);   ASSERT (pAddr>>log2SCACHE_LINE_SIZE == e->pAddr>>log2SCACHE_LINE_SIZE);   e->categ = categ;}/***************************************************************** * FalseSharingEvict *****************************************************************/void FalseSharingEvict(int cpuNum, PA pAddr, int way, int type){   int machine = M_FROM_CPU(cpuNum);   MA mAddr    = PHYS_TO_MEMADDR(machine,pAddr);   PA mAddrOff = (PA)(mAddr-startMA);   uint index;   FalseSharingEntry *e;   FalseSharingBV *modifiedBV;   if (!falseSharing) {       return;    }   ASSERT( startMA <= mAddr && mAddr < endMA);   ASSERT(mAddrOff >= 0);   index = PADDR_TO_INDEX(pAddr,way);   e = (falseSharingAccessed[machine][MCPU_FROM_CPU(cpuNum)])+index;   if( interest(pAddr)) {      LogEntry("evict", cpuNum,"pA=0x%08x index=0x%06x way=%i \n",pAddr,index,way);   }   /* now we know if it is true or false sharing */   if( !e->valid ) {      ASSERT (e->categ < 0);      /*        *miss was not recorded.        *Most likely an instruction miss on that line.       */      return;   }   if (pAddr>>log2SCACHE_LINE_SIZE != e->pAddr>>log2SCACHE_LINE_SIZE) {      LogEntry("FALSESH",cpuNum,"pAddr missmatched %x != %x type=%x \n",               pAddr,e->pAddr,type);      return;   }   ASSERT(e->categ >= 0);   modifiedBV = &falseSharingModifyWords[((mAddrOff>>log2SCACHE_LINE_SIZE)*TOTAL_CPUS) + cpuNum];   if (e->accessedWords & *modifiedBV) {       /* true sharing */      StatRecordIncrement(e->snap, e->PC, e->vAddr,                           falseSharingBucket.trueSharing[e->categ],1);      StatRecordIncrement(e->snap, e->PC, e->vAddr,                           falseSharingBucket.trueSharingStall[e->categ],                          e->stall);            *modifiedBV = 0;   } else {       StatRecordIncrement(e->snap, e->PC, e->vAddr,                           falseSharingBucket.falseSharing[e->categ],1);        StatRecordIncrement(e->snap, e->PC, e->vAddr,                          falseSharingBucket.falseSharingStall[e->categ],                          e->stall);   }     StatRecordFreeSnapshot(e->snap);   e->vAddr = 0;   e->valid = 0;   e->categ = -1;}/***************************************************************** * FalseSharingModify *****************************************************************/void FalseSharingModify(int cpuNum, PA pAddr){   int machine = M_FROM_CPU(cpuNum);   MA mAddr = PHYS_TO_MEMADDR(cpuNum,pAddr);   PA mAddrOff = (PA)(mAddr-startMA);   FalseSharingBV *modifiedBV;   FalseSharingBV mask;   int i;      if (!falseSharing) {       return;    }   ASSERT(startMA <= mAddr && mAddr < endMA);   modifiedBV = &falseSharingModifyWords[(mAddrOff>>log2SCACHE_LINE_SIZE) * TOTAL_CPUS];   mask = falseSharingMaskEntries[machine][pAddr&falseSharingMask];      for(i=0;i<TOTAL_CPUS;i++){      if (i != cpuNum) {         *modifiedBV |= mask;               }      modifiedBV++;   }}   /***************************************************************** * FalseSharingModify * Called when the simulation ends. All true sharing misses * are classified as such.  *****************************************************************/void FalseSharingCleanup(void){   int lines;   int cpuNum;   int index;   int count=0;   if (!falseSharing) return;   ASSERT (SCACHE_SIZE && SCACHE_LINE_SIZE);   lines = SCACHE_SIZE / SCACHE_LINE_SIZE;   for(cpuNum=0; cpuNum < TOTAL_CPUS;cpuNum++) {      int machine = M_FROM_CPU(cpuNum);      for(index=0;index < lines; index++){          FalseSharingEntry *e =             (falseSharingAccessed[machine][MCPU_FROM_CPU(cpuNum)])+index;         FalseSharingBV *modifiedBV =             &falseSharingModifyWords[index*TOTAL_CPUS + cpuNum];                  if( !e->valid ) continue;         ASSERT(e->categ >= 0);         if (e->accessedWords & *modifiedBV) {             /* true sharing */            count++;            StatRecordIncrement(e->snap, e->PC, e->vAddr,                                 falseSharingBucket.trueSharing[e->categ],1);            StatRecordIncrement(e->snap, e->PC, e->vAddr,                                 falseSharingBucket.trueSharingStall[e->categ],                                e->stall);             *modifiedBV = 0;            StatRecordFreeSnapshot(e->snap);            e->vAddr = 0;            e->valid = 0;            e->categ = -1;         }      }   }   CPUWarning("FALSE SHARING CLEANUP : %d true sharings  detected \n",count);}

⌨️ 快捷键说明

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