📄 cachesim.c
字号:
/*----------------------------------------------------------------------*//*-- A generic, simple cache simulator --*//*-- to be linked into annotated executables cachesim.c --*//*----------------------------------------------------------------------*//* This file is part of Cacheprof, a profiling tool for finding sources of cache misses in programs. Copyright (C) 1999 Julian Seward (jseward@acm.org) Home page: http://www.cacheprof.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. The GNU General Public License is contained in the file LICENSE.*/#include <stdio.h>#include <stdlib.h>#include <sys/times.h>#include <sys/resource.h>typedef int Int32;typedef unsigned int UInt32;typedef unsigned long long int UInt64;typedef double Double;#define int fooble#define double fooblestatic Int32 num_initcalls = 0;static Int32 num_donecalls = 0;static Int32 register_level1 = 0;static Int32 register_level2 = 0;static UInt64 n_r1 = 0, n_mr1 = 0;static UInt64 n_r2 = 0, n_mr2 = 0;static UInt64 n_r4 = 0, n_mr4 = 0;static UInt64 n_r8 = 0, n_mr8 = 0;static UInt64 n_w1 = 0, n_mw1 = 0;static UInt64 n_w2 = 0, n_mw2 = 0;static UInt64 n_w4 = 0, n_mw4 = 0;static UInt64 n_w8 = 0, n_mw8 = 0; UInt64 cacheprof_icount = 0; UInt64 cacheprof_level1_reads = 0; UInt64 cacheprof_level1_writes = 0;static Double start_time;static Int32 quiet = 0;static Int32 inited = 0;typedef struct { UInt32 filenameno; UInt32 lineno; UInt32 funcnameno; UInt64 tno; UInt64 mno; } CC_ty;static void fileerr ( void );static Double getTime ( void );#define PROF_FILE "cacheprof.out"/* The cache simulation proper is in the automatically generated file cachesim_doref.c.*/#include "cachesim_doref.c"static void init ( void ){ Int32 i, j; FILE* prof; char* p; inited = 1; n_r1 = n_r2 = n_r4 = n_r8 = n_w1 = n_w2 = n_w4 = n_w8 = 0; n_mr1 = n_mr2 = n_mr4 = n_mr8 = n_mw1 = n_mw2 = n_mw4 = n_mw8 = 0; cacheprof_icount = 0; cacheprof_level1_reads = 0; cacheprof_level1_writes = 0; quiet = 0; p = getenv("CACHEPROF"); if (p && (strcmp("-q",p)==0 || strcmp("--quiet",p)==0)) quiet = 1; cachesim_initcache(); prof = fopen(PROF_FILE, "w"); if (!prof) fileerr(); fclose(prof); start_time = getTime();}void cacheprof_log_Rd1 ( CC_ty* pp, void* a ){ n_r1++; pp->tno++; if (cachesim_doref(a)) { n_mr1++; pp->mno++; };}void cacheprof_log_Rd2 ( CC_ty* pp, void* a ){ n_r2++; pp->tno++; if (cachesim_doref(a)) { n_mr2++; pp->mno++; };}void cacheprof_log_Rd4 ( CC_ty* pp, void* a ){ n_r4++; pp->tno++; if (cachesim_doref(a)) { n_mr4++; pp->mno++; };}void cacheprof_log_Rd8 ( CC_ty* pp, void* a ){ n_r8++; pp->tno++; if (cachesim_doref(a)) { n_mr8++; pp->mno++; };}void cacheprof_log_Mo1 ( CC_ty* pp, void* a ){ n_r1++; n_w1++; pp->tno += 2; if (cachesim_doref(a)) { n_mr1++; pp->mno++; };}void cacheprof_log_Mo2 ( CC_ty* pp, void* a ){ n_r2++; n_w2++; pp->tno += 2; if (cachesim_doref(a)) { n_mr2++; pp->mno++; };}void cacheprof_log_Mo4 ( CC_ty* pp, void* a ){ n_r4++; n_w4++; pp->tno += 2; if (cachesim_doref(a)) { n_mr4++; pp->mno++; };}void cacheprof_log_Mo8 ( CC_ty* pp, void* a ){ n_r8++; n_w8++; pp->tno += 2; if (cachesim_doref(a)) { n_mr8++; pp->mno++; };}void cacheprof_log_Wr1 ( CC_ty* pp, void* a ){ n_w1++; pp->tno++; if (cachesim_doref(a)) { n_mw1++; pp->mno++; };}void cacheprof_log_Wr2 ( CC_ty* pp, void* a ){ n_w2++; pp->tno++; if (cachesim_doref(a)) { n_mw2++; pp->mno++; };}void cacheprof_log_Wr4 ( CC_ty* pp, void* a ){ n_w4++; pp->tno++; if (cachesim_doref(a)) { n_mw4++; pp->mno++; };}void cacheprof_log_Wr8 ( CC_ty* pp, void* a ){ n_w8++; pp->tno++; if (cachesim_doref(a)) { n_mw8++; pp->mno++; };}/*---------------------------------------------------------*//*-- Startup and shutdown actions --*//*---------------------------------------------------------*/staticvoid pComma ( FILE* f, Int32 width, UInt64 i ){ char buf1[50]; char buf2[50]; Int32 j, k, n; sprintf(buf1, "%Lu", i); j = strlen(buf1); n = 0; for (k = 0; k < j; k++) { buf2[n++] = buf1[k]; if ((j-k) % 3 == 1 && k < j-1) buf2[n++] = ','; } buf2[n] = 0; if (width < 0) { width = -width; fprintf ( f, "%s", buf2 ); for (j = 0; j < width-n; j++) fprintf ( f, " " ); } else { for (j = 0; j < width-n; j++) fprintf ( f, " " ); fprintf ( f, "%s", buf2 ); }}staticDouble getTime ( void ){ Double usertime; struct rusage usage; getrusage ( RUSAGE_SELF, &usage ); usertime = (Double)usage.ru_utime.tv_sec + (Double)usage.ru_utime.tv_usec / 1000000.0; return usertime;}static void showMIPS ( void ){ start_time = getTime() - start_time; if (start_time < 0.0) start_time = 0.0; if (!quiet) fprintf ( stderr, "==cacheprof== %.2f seconds, %.2f MIPS\n", start_time, ((Double)cacheprof_icount) / start_time / 1000000.0 );}static void fileerr ( void ){ fprintf ( stderr, "==cacheprof== Can't create/write output file `%s'.\n" "==cacheprof== Giving up. Bye.\n", PROF_FILE ); exit(1);}void mixup ( void ){ fprintf ( stderr, "==cacheprof== You can't mix level-1 and level-2 profiling.\n" "==cacheprof== Giving up. Bye.\n" ); exit(1);}void cacheprof_register1_module ( void ){ num_initcalls++; if (num_initcalls == 1) { init(); if (!quiet) fprintf ( stderr, "==cacheprof== level-1 instrumented program: startup\n" ); } register_level1 = 1; if (register_level2) mixup();}void cacheprof_register2_module ( void* v ){ num_initcalls++; if (num_initcalls == 1) { init(); if (!quiet) fprintf ( stderr, "==cacheprof== level-2 instrumented program: startup\n" ); } register_level2 = 1; if (register_level1) mixup();}static void dump_summary_stats ( FILE* prof ){ fprintf(prof, "%Lu\n", cacheprof_icount ); fprintf(prof, "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", n_r1, n_r2, n_r4, n_r8, n_mr1, n_mr2, n_mr4, n_mr8 ); fprintf(prof, "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", n_w1, n_w2, n_w4, n_w8, n_mw1, n_mw2, n_mw4, n_mw8 ); fflush(prof);}static char* emitstr ( FILE* f, char* s ){ while (*s) { fputc ( *s, f ); s++; } return s;}staticvoid extend_summary ( UInt64 tot_insns, UInt64 tot_rd, UInt64 tot_wr, UInt64 tot_rd_miss, UInt64 tot_wr_miss ){ FILE* summary; summary = fopen ( "cacheprof.out.summary", "a" ); if (summary) { fprintf ( summary, "OTHER(%Lu, %Lu, %Lu, %Lu, %Lu)\n", tot_insns, tot_rd, tot_wr, tot_rd_miss, tot_wr_miss ); fflush ( summary ); fclose ( summary ); }}void cacheprof_finalise1_module ( void ){ Int32 r; FILE* summary; num_donecalls++; if (num_donecalls == 1) { if (!quiet) { fprintf ( stderr, "==cacheprof== level-1 instrumented program: run complete\n" ); fprintf ( stderr, "==cacheprof== " ); pComma ( stderr, 13, cacheprof_icount ); fprintf ( stderr, " insns\n==cacheprof== " ); pComma ( stderr, 13, cacheprof_level1_reads + cacheprof_level1_writes ); fprintf ( stderr, " refs (" ); pComma ( stderr, 13, cacheprof_level1_reads ); fprintf ( stderr, " rd + " ); pComma ( stderr, 13, cacheprof_level1_writes ); fprintf ( stderr, " wr)\n" ); showMIPS(); } extend_summary ( cacheprof_icount, cacheprof_level1_reads, cacheprof_level1_writes, 0, 0 ); /* Try to nuke cacheprof.out, but don't worry too much if it's not possible. */ r = remove ( PROF_FILE ); }}void cacheprof_finalise2_module ( void* v ){ UInt32* pre = (UInt32*) v; UInt32 n_filenames = pre[0]; UInt32 n_funcnames = pre[1]; UInt32 n_ccs = pre[2]; CC_ty* ccs = (CC_ty*)(pre[3]); char* strtab = (char*)(&pre[4]); char* p; FILE* prof; UInt32 i; UInt32 n_ccs_live; num_donecalls++; if (num_donecalls == 1) { if (!quiet) { fprintf ( stderr, "==cacheprof== level-2 instrumented program: run complete\n" ); fprintf ( stderr, "==cacheprof== " ); pComma ( stderr, 13, cacheprof_icount ); fprintf ( stderr, " insns\n==cacheprof== " ); pComma ( stderr, 13, n_r1+n_r2+n_r4+n_r8 + n_w1+n_w2+n_w4+n_w8 ); fprintf ( stderr, " refs (" ); pComma ( stderr, 13, n_r1 + n_r2 + n_r4 + n_r8 ); fprintf ( stderr, " rd + " ); pComma ( stderr, 13, n_w1 + n_w2 + n_w4 + n_w8 ); fprintf ( stderr, " wr)\n==cacheprof== " ); pComma ( stderr, 13, n_mr1+n_mr2+n_mr4+n_mr8 + n_mw1+n_mw2+n_mw4+n_mw8 ); fprintf ( stderr, " misses (" ); pComma ( stderr, 13, n_mr1+n_mr2+n_mr4+n_mr8 ); fprintf ( stderr, " rd + " ); pComma ( stderr, 13, n_mw1+n_mw2+n_mw4+n_mw8 ); fprintf ( stderr, " wr)\n" ); showMIPS(); } extend_summary ( cacheprof_icount, n_r1 + n_r2 + n_r4 + n_r8, n_w1 + n_w2 + n_w4 + n_w8, n_mr1 + n_mr2 + n_mr4 + n_mr8, n_mw1 + n_mw2 + n_mw4 + n_mw8 ); } prof = fopen(PROF_FILE, "a"); if (!prof) fileerr(); if (num_donecalls == 1) dump_summary_stats(prof); n_ccs_live = 0; for (i = 0; i < n_ccs; i++) if (ccs[i].tno > 0) n_ccs_live++; fprintf ( prof, "%u %u %u\n", n_filenames, n_funcnames, n_ccs_live ); p = strtab; for (i = 0; i < n_filenames; i++) { fprintf ( prof, " " ); p = emitstr ( prof, p ); p++; fprintf ( prof, "\n" ); } for (i = 0; i < n_funcnames; i++) { fprintf ( prof, " " ); p = emitstr ( prof, p ); p++; fprintf ( prof, "\n" ); } for (i = 0; i < n_ccs; i++) { /* don't put inactive CCs into cacheprof.out */ if (ccs[i].tno == 0) { if (ccs[i].mno != 0) fprintf(stderr, "==cacheprof== Simulator internal consistency error!\n" ); continue; } else { fprintf ( prof, " %d %d %d %Lu %Lu\n", ccs[i].filenameno, ccs[i].lineno, ccs[i].funcnameno, ccs[i].tno, ccs[i].mno ); } } fflush(prof); fclose(prof);}/*----------------------------------------------------------------------*//*-- end cachesim.c --*//*----------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -