#line 7420 "smat.w" #line 5507 "smat.w" #include "smat.h" #include #include #include #include #include #include #include #include #ifdef linux #include #endif #line 7420 "smat.w" #include "smatsim.h" using namespace std; static int verbose, types, dump; #line 7458 "smat.w" smat_cache<'0', NREG * 4, 4, NREG, 0, true, false, smat_cache<'1', L1_SIZE, L1_BLOCK, L1_ASSOC, L1_LATENCY, L1_WB, true, smat_cache_main > > cache_g; smat_cache<'0', NREG * 4, 4, NREG, 0, true, false, smat_cache<'1', L1_SIZE, L1_BLOCK, L1_ASSOC, L1_LATENCY, L1_WB, false, smat_cache_main > > cache; #line 7426 "smat.w" #line 7469 "smat.w" static void config() { cout << "Number of registers\t" << NREG << " (32-bit)\n"; char assoc[64]; if (L1_ASSOC == L1_SIZE / L1_BLOCK) sprintf(assoc, "Fully associative"); else if (L1_ASSOC == 1) sprintf(assoc, "Direct mapped"); else sprintf(assoc, "%d-way set associative", L1_ASSOC); cout << "L1 cache block size\t" << L1_BLOCK << " bytes\n" << "L1 cache cache size\t" << L1_SIZE << " bytes (" << (L1_SIZE / L1_BLOCK) << " blocks)\n" << "L1 cache associativity\t" << assoc << '\n' << "L1 cache write policy\t" << (L1_WB ? "write back" : "write through") << '\n' << "L1 cache hit time\t" << L1_LATENCY << " clock cycle(s)\n"; cout << "Main memory hit time\t" << MAIN_LATENCY << " clock cycle(s)\n"; } #line 7427 "smat.w" #line 7552 "smat.w" template int sim(Cache& c) { istream_iterator first(cin), last; vector clocks(4), hits(4), misses(4); // i, v, d, p int t = 0; size_t hit = 0, miss = 0; for (; first != last; ++first) { if (0 < dump) { cout << c.time('0'); (*first).write_readable(); } switch ((*first).code) { case SMAT_MOV: case SMAT_IADD: case SMAT_ISUB: case SMAT_IMUL: case SMAT_IDIV: case SMAT_IMOD: case SMAT_ILSHIFT: case SMAT_IRSHIFT: case SMAT_IAND: case SMAT_IOR: case SMAT_IXOR: case SMAT_MINUS: case SMAT_CMPL: case SMAT_CCTOR: case SMAT_BCTOR: c.read((*first).src1, (*first).len); c.write((*first).dst, (*first).len); break; case SMAT_INC: case SMAT_DEC: c.read((*first).src1, (*first).len); c.write((*first).src1, (*first).len); break; case SMAT_READ: case SMAT_IEQ: case SMAT_INEQ: case SMAT_IGT: case SMAT_IGEQ: case SMAT_ILT: case SMAT_ILEQ: c.read((*first).src1, (*first).len); break; case SMAT_WRITE: c.write((*first).src1, (*first).len); break; case SMAT_DTOR: c.dtor((*first).src1, (*first).len); break; case SMAT_AND: case SMAT_OR: case SMAT_XOR: case SMAT_ADD: case SMAT_SUB: case SMAT_MUL: case SMAT_DIV: case SMAT_MOD: case SMAT_LSHIFT: case SMAT_RSHIFT: c.read((*first).src1, (*first).len); c.read((*first).src2, (*first).len); c.write((*first).dst, (*first).len); break; case SMAT_EQ: case SMAT_NEQ: case SMAT_GT: case SMAT_GEQ: case SMAT_LT: case SMAT_LEQ: c.read((*first).src1, (*first).len); c.read((*first).src2, (*first).len); break; case SMAT_FMARK: cout << (*first).src1 << '\t'; // c.report_simple(); break; case SMAT_NOP: case SMAT_CTOR: break; default: return 1; } if (types) { int new_t = c.time('0'); size_t new_hit = c.hit('1'), new_miss = c.miss('1'); clocks[(*first).type] += new_t - t; hits[(*first).type] += new_hit - hit; misses[(*first).type] += new_miss - miss; t = new_t; hit = new_hit; miss = new_miss; } if (1 < dump) c.dump(); } #line 7651 "smat.w" if (verbose) { #line 7666 "smat.w" cout.precision(3); cout << "Register hits\t\t" << c.hit('0') << " hits (" << c.hit('0') - c.whit('0') << "r + " << c.whit('0') << "w)\n"; cout << "Register misses\t\t" << c.miss('0') << " misses (" << c.miss('0') - c.wmiss('0') << "r + " << c.wmiss('0') << "w, " << (double)c.miss('0') / (c.hit('0') + c.miss('0')) * 100 << "%)\n"; cout << "Register writebacks\t" << c.wb('0') << " (" << (double)c.wb('0') / c.miss('0') * 100 << "% of all misses)\n"; cout << "Register reads\t\t" << c.r('0') << " bytes\n"; cout << "Register writes\t\t" << c.w('0') << " bytes\n\n"; cout << "L1 cache hits\t\t" << c.hit('1') << " hits (" << c.hit('1') - c.whit('1') << "r + " << c.whit('1') << "w)\n"; cout << "L1 cache misses\t\t" << c.miss('1') << " misses (" << c.miss('1') - c.wmiss('1') << "r + " << c.wmiss('1') << "w, " << (double)c.miss('1') / (c.hit('1') + c.miss('1')) * 100 << "%)\n"; cout << "L1 cache writebacks\t" << c.wb('1') << " (" << (double)c.wb('1') / c.miss('1') * 100 << "% of all misses)\n"; cout << "L1 cache reads\t\t" << c.r('1') << " bytes\n"; cout << "L1 cache writes\t\t" << c.w('1') << " bytes\n\n"; cout << "Main memory reads\t" << c.r('m') << " bytes\n"; cout << "Main memory writes\t" << c.w('m') << " bytes\n\n"; cout << "Total clock cycles\t" << c.time('0') << " clocks\n"; #line 7653 "smat.w" } else if (! types) { cout << c.hit('1') << " hits, " << c.miss('1') << " misses, " << c.time('0') << " clocks\n"; } #line 7701 "smat.w" if (types) { char *title[] = { "Iterator type\t\t", "Value type\t\t", "Difference type\t\t", "Pointer type\t\t" }; cout << "Total\t\t\t" << c.hit('1') << " hits, " << c.miss('1') << " misses, " << c.time('0') << " cycles\n"; for (int i = 0; i < 4; ++i) { cout << title[i] << hits[i] << " hits, " << misses[i] << " misses, " << clocks[i] << " cycles\n"; } } #line 7661 "smat.w" #line 7641 "smat.w" return 0; } #line 7428 "smat.w" #line 9187 "smat.w" template static bool lazy_atoi(T* dst, const char *s) { std::istringstream ist(s); return (!(ist >> *dst).fail() && (ist >> std::ws).eof()) ? true : false; } #line 7429 "smat.w" #line 7493 "smat.w" static void usage(char *progname, int status) { if (status != 0) std::cerr << "Try `" << progname << " -h' for more information.\n"; else { std::cout << "Usage: " << progname << " [OPTION]... < TRACEFILE\n\ Simulate cache behavior caused by the given TRACEFILE.\n\ \n\ -c display cache parameters and exit\n\ -d debug mode (-dd gives you more)\n\ -g FILE output time-position information to FILE (for internal use)\n\ -t type analysis\n\ -v generate detailed statistics\n\ \n\ -h display this help and exit\n"; } exit(status); } #line 7430 "smat.w" int main(int argc, char *argv[]) { int c; ofstream graph_os; ios::sync_with_stdio(false); cin.tie(0); #line 7515 "smat.w" while ((c = getopt(argc, argv, "cdg:hvt")) != -1) { switch (c) { case 'c': config(); return EXIT_SUCCESS; break; case 'd': ++dump; break; case 'g': graph_os.open(optarg); if (!graph_os) { cerr << argv[0] << ": " << optarg << ": " << strerror(errno) << '\n'; return EXIT_FAILURE; } SMAT_SET_OSTREAM(graph_os); break; case 'h': usage(argv[0], EXIT_SUCCESS); break; case 't': ++types; break; case 'v': ++verbose; break; default: usage(argv[0], EXIT_FAILURE); break; } } if (optind != argc) usage(argv[0], EXIT_FAILURE); #line 7440 "smat.w" if (graph_os.is_open()) sim(cache_g); else sim(cache); return 0; }