2 Copyright (c) 2020 Peter Hsu. All Rights Reserved. See LICENCE file for details.
20 #include "tagonlycache.h"
23 #define REPORT_FREQUENCY 10
25 #define RT_READ 0b0000000000000010L
26 #define RT_WRITE 0b0000000000000100L
27 #define RT_GETPUT 0b0000000000010000L
28 #define RT_LEVEL_SHIFT 5
29 #define RT_L0_CACHE 0b0000000000100000L
30 #define RT_L1_CACHE 0b0000000001000000L
31 #define RT_L2_CACHE 0b0000000010000000L
32 #define RT_L3_CACHE 0b0000000100000000L
33 #define RT_INSN_CACHE 0b0000001000000000L
34 #define RT_DATA_CACHE 0b0000010000000000L
39 struct fifo_t
* outbuf
;
40 long report_frequency
;
42 void allocError(uint64 n
, char * thing
, char * filename
, int32 linenumber
)
44 printf("\nmemory allocation failed trying to allocate %lld bytes for a '%s' on line %d in file %s",
45 n
, thing
, linenumber
, filename
);
48 int strchrs(const char* str
, const char* keys
)
50 for (char k
=*keys
++; k
; k
=*keys
++)
56 static const char* in_path
;
57 static const char* out_path
;
58 static const char* flags
;
59 static long lgline
, ways
, lgsets
;
60 static long report
, quiet
;
62 const struct options_t opt
[] =
63 { { "--in=s", .s
=&in_path
, .ds
=0, .h
="Trace file =name (from caveat, pipesim, or cachesim)" },
64 { "--line=i", .i
=&lgline
, .di
=6, .h
="Cache line size is 2^ =n bytes" },
65 { "--ways=i", .i
=&ways
, .di
=8, .h
="Cache is =w ways set associativity" },
66 { "--sets=i", .i
=&lgsets
, .di
=11, .h
="Cache has 2^ =n sets per way" },
67 { "--sim=s", .s
=&flags
, .ds
=0, .h
="Simulate all access =types [iIdD0123rRwW] default all" },
68 { "--out=s", .s
=&out_path
, .ds
=0, .h
="Output next-level misses to trace =name" },
69 { "--report=i", .i
=&report
, .di
=10, .h
="Progress report every =number million instructions" },
70 { "--quiet", .b
=&quiet
, .bv
=1, .h
="Don't report progress to stderr" },
71 { "-q", .b
=&quiet
, .bv
=1, .h
="short for --quiet" },
74 const char* usage
= "cachesim --in=trace [cachesim-options]";
76 int main(int argc
, const char** argv
)
78 int numopts
= parse_options(argv
+1);
79 if (argc
== numopts
+1 || !in_path
)
81 cacheData
* cache
= (cacheData
*)newCacheData();
82 configureCache(cache
, (char*)"Wilson's cache", ways
, lgline
, lgsets
);
83 long insns
=0, now
=0, refs
=0, misses
=0;
84 report_frequency
= (report
? report
: REPORT_FREQUENCY
) * 1000000;
85 long next_report
= report_frequency
;
88 if (strchrs(flags
, "rR") && !strchrs(flags
, "wW"))
90 else if (strchrs(flags
, "wW") && !strchrs(flags
, "rR"))
93 filter
|= RT_READ
| RT_WRITE
;
95 if (strchrs(flags
, "iI") && !strchrs(flags
, "dD"))
96 filter
|= RT_INSN_CACHE
;
97 else if (strchrs(flags
, "dD") && !strchrs(flags
, "iI"))
98 filter
|= RT_DATA_CACHE
;
100 filter
|= RT_INSN_CACHE
| RT_DATA_CACHE
;
102 filter
|= RT_L0_CACHE
;
103 if (!strchrs(flags
, "0")) {
104 filter
|= RT_L1_CACHE
;
105 if (!strchrs(flags
, "1")) {
106 filter
|= RT_L2_CACHE
;
107 if (!strchrs(flags
, "2"))
108 filter
|= RT_L3_CACHE
;
113 filter
= ~0L; /* default simulate all references */
115 fifo
= fifo_open(in_path
);
117 outbuf
= fifo_create(out_path
, 0);
118 clock_t start_tick
= clock();
120 for (uint64_t tr
=fifo_get(fifo
); tr_code(tr
)!=tr_eof
; tr
=fifo_get(fifo
)) {
125 reftype
= is_write(tr
) ? RT_WRITE
: RT_READ
;
128 reftype
|= (1L<<tr_clevel(tr
)) << RT_LEVEL_SHIFT
;
130 if (reftype
& filter
) {
133 if (!lookup(is_write(tr
)?'w':'r', tr_value(tr
), cache
, &way
)) {
136 fifo_put(outbuf
, tr
);
138 if (refs
>= next_report
&& !quiet
) {
139 double elapse
= (clock() - start_tick
) / CLOCKS_PER_SEC
;
140 fprintf(stderr
, "\r%3.1fB insns %3.1fB cycles %3.1fB refs %3.1f misses/Kinsns in %3.1fs for %3.1f MIPS ", insns
/1e9
, now
/1e9
, refs
/1e9
, misses
/(insns
/1e3
), elapse
, insns
/1e6
/elapse
);
141 next_report
+= REPORT_FREQUENCY
;
144 else if (out_path
) /* pass to next stage */
145 fifo_put(outbuf
, tr
);
148 if (tr_code(tr
) == tr_cycles
) {
151 fifo_put(outbuf
, tr
);
154 if (tr_code(tr
) == tr_icount
) {
155 insns
= tr_value(tr
);
157 fifo_put(outbuf
, tr
);
160 if (is_frame(tr
) && out_path
) {
161 fifo_put(outbuf
, tr
);
165 fprintf(stderr
, "\n\n");
166 reportCacheStats(cache
);
169 fifo_put(outbuf
, trM(tr_eof
, 0));