diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2017-05-28 23:42:54 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2017-05-28 23:57:19 -0700 |
commit | b2f699e14f02ba503c7a70afc3e9b749ac61f3d7 (patch) | |
tree | 1c584a99e16e4159ab694aefcd3c0210cd653183 | |
parent | 5987486862b8c989452bc62d359168a5686b462e (diff) | |
download | mu-b2f699e14f02ba503c7a70afc3e9b749ac61f3d7.tar.gz |
3888 - beginnings of a profiler
Time to make my ad hoc commented out code fragments a first-class feature.
-rw-r--r-- | 020run.cc | 69 | ||||
-rw-r--r-- | 026call.cc | 5 | ||||
-rw-r--r-- | 054static_dispatch.cc | 3 | ||||
-rw-r--r-- | 101run_sandboxed.cc | 5 |
4 files changed, 60 insertions, 22 deletions
diff --git a/020run.cc b/020run.cc index 15644843..9b20a61e 100644 --- a/020run.cc +++ b/020run.cc @@ -48,9 +48,6 @@ struct routine { :(before "End Globals") routine* Current_routine = NULL; -map<string, int> Instructions_running; -map<string, int> Locations_read; -map<string, int> Locations_read_by_instruction; :(before "End Setup") Current_routine = NULL; @@ -65,7 +62,6 @@ void run(const recipe_ordinal r) { void run_current_routine() { while (should_continue_running(Current_routine)) { // beware: may modify Current_routine // Running One Instruction -//? Instructions_running[current_recipe_name()]++; if (current_instruction().is_label) { ++current_step_index(); continue; } trace(Initial_callstack_depth + Trace_stream->callstack_depth, "run") << to_string(current_instruction()) << end(); if (get_or_insert(Memory, 0) != 0) { @@ -139,6 +135,11 @@ int& current_step_index() { } //: hook replaced in a later layer +recipe_ordinal currently_running_recipe() { + return Current_routine->running_recipe; +} + +//: hook replaced in a later layer const string& current_recipe_name() { return get(Recipe, Current_routine->running_recipe).name; } @@ -232,23 +233,6 @@ else if (is_equal(*arg, "--trace")) { } :(code) -void dump_profile() { - for (map<string, int>::iterator p = Instructions_running.begin(); p != Instructions_running.end(); ++p) { - cerr << p->first << ": " << p->second << '\n'; - } - cerr << "== locations read\n"; - for (map<string, int>::iterator p = Locations_read.begin(); p != Locations_read.end(); ++p) { - cerr << p->first << ": " << p->second << '\n'; - } - cerr << "== locations read by instruction\n"; - for (map<string, int>::iterator p = Locations_read_by_instruction.begin(); p != Locations_read_by_instruction.end(); ++p) { - cerr << p->first << ": " << p->second << '\n'; - } -} -:(before "End One-time Setup") -//? atexit(dump_profile); - -:(code) void cleanup_main() { if (Save_trace && Trace_stream) { cerr << "writing trace to 'last_run'\n"; @@ -456,3 +440,46 @@ def main [ 1:num, 2:num <- copy 2 ,2 ] +mem: storing 2 in location 1 + +//:: Counters for trying to understand where Mu programs are spending their +//:: time. + +:(before "End Globals") +bool Run_profiler = false; +// We'll key profile information by recipe_ordinal rather than name because +// it's more efficient, and because later layers will show more than just the +// name of a recipe. +// +// One drawback: if you're clearing recipes your profile will be inaccurate. +// So far that happens in tests, and in `run-sandboxed` in a later layer. +map<recipe_ordinal, int> Instructions_running; +:(before "End Commandline Options(*arg)") +else if (is_equal(*arg, "--profile")) { + Run_profiler = true; +} +:(after "Running One Instruction") +if (Run_profiler) Instructions_running[currently_running_recipe()]++; +:(before "End One-time Setup") +atexit(dump_profile); +:(code) +void dump_profile() { + if (!Run_profiler) return; + if (Run_tests) { + cerr << "It's not a good idea to profile a run with tests, since tests can create conflicting recipes and mislead you. To try it anyway, comment out this check in the code.\n"; + return; + } + ofstream fout; + fout.open("profile.instructions"); + if (fout) { + for (map<recipe_ordinal, int>::iterator p = Instructions_running.begin(); p != Instructions_running.end(); ++p) { + fout << std::setw(9) << p->second << ' ' << header_label(p->first) << '\n'; + } + } + fout.close(); + // End dump_profile +} + +// overridden in a later layer +string header_label(const recipe_ordinal r) { + return get(Recipe, r).name; +} diff --git a/026call.cc b/026call.cc index 81012350..15e44d35 100644 --- a/026call.cc +++ b/026call.cc @@ -79,6 +79,11 @@ int& current_step_index() { assert(!Current_routine->calls.empty()); return current_call().running_step_index; } +:(replace{} "recipe_ordinal currently_running_recipe()") +recipe_ordinal currently_running_recipe() { + assert(!Current_routine->calls.empty()); + return current_call().running_recipe; +} :(replace{} "const string& current_recipe_name()") const string& current_recipe_name() { assert(!Current_routine->calls.empty()); diff --git a/054static_dispatch.cc b/054static_dispatch.cc index e73ab3f5..450d887f 100644 --- a/054static_dispatch.cc +++ b/054static_dispatch.cc @@ -566,10 +566,11 @@ def foo x:num -> y:num [ # number variant is preferred +mem: storing 35 in location 1 -:(code) +:(replace{} "string header_label(const recipe_ordinal r)") string header_label(const recipe_ordinal r) { return header_label(get(Recipe, r)); } +:(code) string header_label(const recipe& caller) { ostringstream out; out << "recipe " << caller.name; diff --git a/101run_sandboxed.cc b/101run_sandboxed.cc index 1904942f..06b1cb04 100644 --- a/101run_sandboxed.cc +++ b/101run_sandboxed.cc @@ -130,6 +130,7 @@ bool run_interactive(int address) { //: Carefully update all state to exactly how it was -- including snapshots. :(before "End Globals") +bool Run_profiler_stash = false; map<string, recipe_ordinal> Recipe_ordinal_snapshot_stash; map<recipe_ordinal, recipe> Recipe_snapshot_stash; map<string, type_ordinal> Type_ordinal_snapshot_stash; @@ -145,6 +146,8 @@ void run_code_begin(bool should_stash_snapshots) { // stuff to undo later, in run_code_end() Hide_errors = true; Disable_redefine_checks = true; + Run_profiler_stash = Run_profiler; + Run_profiler = false; if (should_stash_snapshots) stash_snapshots(); Save_trace_stream = Trace_stream; @@ -155,6 +158,8 @@ void run_code_begin(bool should_stash_snapshots) { void run_code_end() { Hide_errors = false; Disable_redefine_checks = false; + Run_profiler = Run_profiler_stash; + Run_profiler_stash = false; //? ofstream fout("sandbox.log"); //? fout << Trace_stream->readable_contents(""); //? fout.close(); |