Simulation is useful not only for verifying the correctness of a
proposed machine design but also for measuring the machine's
performance. For example, we can install in our simulation program a
meter
that measures the number of stack operations used in a
computation. To do this, we modify our simulated stack to keep track
of the number of times registers are saved on the stack and the
maximum depth reached by the stack, and add a message to the stack's
interface that prints the statistics, as shown below.
We also add an operation to the basic machine model to print the
stack statistics, by initializing
the_ops
in
make_new_machine
to
list(list("initialize_stack",
() => stack("initialize")),
list("print_stack_statistics",
() => stack("print_statistics")));function make_stack() {
let stack = null;
let number_pushes = 0;
let max_depth = 0;
let current_depth = 0;
function push(x) {
stack = pair(x, stack);
number_pushes = number_pushes + 1;
current_depth = current_depth + 1;
max_depth = math_max(current_depth, max_depth);
return "done";
}
function pop() {
if (is_null(stack)) {
error("empty stack -- pop");
} else {
const top = head(stack);
stack = tail(stack);
current_depth = current_depth - 1;
return top;
}
}
function initialize() {
stack = null;
number_pushes = 0;
max_depth = 0;
current_depth = 0;
return "done";
}
function print_statistics() {
display("total pushes = " + stringify(number_pushes));
display("maximum depth = " + stringify(max_depth));
}
function dispatch(message) {
return message === "push"
? push
: message === "pop"
? pop()
: message === "initialize"
? initialize()
: message === "print_statistics"
? print_statistics()
: error(message, "unknown request -- stack");
}
return dispatch;
}
Exercises 5.14 through 5.18 describe other useful monitoring and debugging features that can be added to the register-machine simulator.
set_breakpoint(gcd_machine, "test_b", 4)