1 /**
2 Copyright: Copyright (c) 2014 Andrey Penechko.
3 License: a$(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module emulator.dcpu.emulationstats;
8 
9 import emulator.dcpu.constants;
10 import emulator.dcpu.instruction;
11 
12 struct EmulationStatistics
13 {
14 	ulong totalInstrDone;
15 	ulong cyclesDone;
16 	ulong[32] basicDoneTimes;
17 	ulong[32] specialDoneTimes;
18 	ulong[4] sizesOfDoneInstrs;
19 	ulong[3] numOperandsDone;
20 
21 	void onInstructionDone(ref const Instruction instr, ulong cycles)
22 	{
23 		if (instr.operands == 0) return;
24 
25 		cyclesDone += cycles;
26 		++totalInstrDone;
27 		if (instr.operands == 2) ++basicDoneTimes[instr.opcode];
28 		else if (instr.operands == 1) ++specialDoneTimes[instr.opcode];
29 		
30 		++numOperandsDone[instr.operands];
31 		++sizesOfDoneInstrs[instr.size];
32 	}
33 
34 	void onInstructionUndone(ref const Instruction instr, ulong cycles)
35 	{
36 		if (instr.operands == 0) return;
37 		
38 		cyclesDone -= cycles;
39 		--totalInstrDone;
40 		if (instr.operands == 2) --basicDoneTimes[instr.opcode];
41 		else if (instr.operands == 1) --specialDoneTimes[instr.opcode];
42 		
43 		--numOperandsDone[instr.operands];
44 		--sizesOfDoneInstrs[instr.size];
45 	}
46 
47 	void reset()
48 	{
49 		totalInstrDone = 0;
50 		cyclesDone = 0;
51 		basicDoneTimes[] = 0;
52 		specialDoneTimes[] = 0;
53 		numOperandsDone[] = 0;
54 		sizesOfDoneInstrs[] = 0;
55 	}
56 
57 	void print()
58 	{
59 		import std.stdio;
60 
61 		writefln("---------------------------------- Statistics ----------------------------------");
62 		writefln("Cycles: %10s |  Basic   : %10s |  1w instr : %9s",
63 			cyclesDone, numOperandsDone[2], sizesOfDoneInstrs[1]);
64 		writefln("Instrs: %10s |  Special : %10s |  2w instr : %9s  Avg: %5.3s",
65 			totalInstrDone, numOperandsDone[1], sizesOfDoneInstrs[2],
66 			cast(double)(sizesOfDoneInstrs[1] + sizesOfDoneInstrs[2]*2 +
67 				sizesOfDoneInstrs[3]*3)/ totalInstrDone);
68 		writefln("Avg   : %10.4s |                       |  3w instr : %9s",
69 			cast(double)cyclesDone / totalInstrDone, sizesOfDoneInstrs[3]);
70 		writefln("------------------------------- Instruction info -------------------------------");
71 		
72 		uint inRow = 0;
73 		foreach(opcode; 0..32)
74 		{
75 			if (!isValidBasicOpcode[opcode]) continue;
76 
77 			if (inRow == 6)
78 			{
79 				writeln; inRow = 0;
80 			}
81 
82 			writef("%s %7s  ", basicOpcodeNames[opcode], basicDoneTimes[opcode]);
83 
84 			++inRow;
85 		}
86 
87 		foreach(opcode; 0..32)
88 		{
89 			if (!isValidSpecialOpcode[opcode]) continue;
90 
91 			if (inRow == 6)
92 			{
93 				writeln; inRow = 0;
94 			}
95 
96 			writef("%s %7s  ", specialOpcodeNames[opcode], specialDoneTimes[opcode]);
97 
98 			++inRow;
99 		}
100 		writeln;
101 
102 		stdout.flush();
103 	}
104 }