ruby-changes:68870
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:15:00 +0900 (JST)
Subject: [ruby-changes:68870] 7108da16e9 (master): Fix two stats bugs, refactor stats code, add total_insn_count print
https://git.ruby-lang.org/ruby.git/commit/?id=7108da16e9 From 7108da16e9ec39d682572c47ac3e99035c0683f0 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Thu, 8 Apr 2021 14:31:27 -0400 Subject: Fix two stats bugs, refactor stats code, add total_insn_count print --- yjit.rb | 6 ++--- yjit_iface.c | 73 +++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/yjit.rb b/yjit.rb index e1d9c16417..a0ff8d11d2 100644 --- a/yjit.rb +++ b/yjit.rb @@ -30,7 +30,7 @@ module YJIT https://github.com/ruby/ruby/blob/trunk/yjit.rb#L30 comment_idx = 0 cs.disasm(block.code, block.address).each do |i| while (comment = comments[comment_idx]) && comment.address <= i.address - str << " ;#{highlight.call(comment.comment)}\n" + str << " ; #{highlight.call(comment.comment)}\n" comment_idx += 1 end @@ -81,8 +81,8 @@ module YJIT https://github.com/ruby/ruby/blob/trunk/yjit.rb#L81 $stderr.puts("***YJIT: Printing runtime counters from yjit.rb***") - $stderr.puts "Number of bindings allocated: %d\n" % counters[:binding_allocation_count] - $stderr.puts "Number of locals modified through binding: %d\n" % counters[:local_variable_set_count] + $stderr.puts "Number of bindings allocated: %d\n" % counters[:binding_allocations] + $stderr.puts "Number of locals modified through binding: %d\n" % counters[:binding_set] print_counters(counters, prefix: 'oswb_', prompt: 'opt_send_without_block exit reasons: ') print_counters(counters, prefix: 'leave_', prompt: 'leave exit reasons: ') diff --git a/yjit_iface.c b/yjit_iface.c index 3d1a617757..1ac36b8cf2 100644 --- a/yjit_iface.c +++ b/yjit_iface.c @@ -809,44 +809,47 @@ sort_insn_count_array(int64_t *array) https://github.com/ruby/ruby/blob/trunk/yjit_iface.c#L809 return insn_sorting_buffer; } -static void -print_insn_count_buffer(const struct insn_count *buffer, int how_many, int left_pad) +// Compute the total interpreter exit count +static int64_t +calc_total_exit_count() { - size_t longest_insn_len = 0; size_t total_exit_count = 0; + for (int i = 0; i < VM_INSTRUCTION_SIZE; i++) { + total_exit_count += exit_op_count[i]; + } + + return total_exit_count; +} +static void +print_insn_count_buffer(int how_many, int left_pad) +{ + size_t total_exit_count = calc_total_exit_count(); + + // Sort the exit ops by decreasing frequency + const struct insn_count *sorted_exit_ops = sort_insn_count_array(exit_op_count); + + // Compute the longest instruction name + size_t longest_insn_len = 0; for (int i = 0; i < how_many; i++) { - const char *instruction_name = insn_name(buffer[i].insn); + const char *instruction_name = insn_name(sorted_exit_ops[i].insn); size_t len = strlen(instruction_name); if (len > longest_insn_len) { longest_insn_len = len; } - total_exit_count += buffer[i].count; } - // Number of instructions that finish executing in YJIT. See :count-placement:. - int64_t retired_in_yjit = yjit_runtime_counters.exec_instruction - total_exit_count; - - // Average length of instruction sequences executed by YJIT - double avg_len_in_yjit = (double)retired_in_yjit / total_exit_count; - - // Proportion of instructions that retire in YJIT - double total_insns_count = retired_in_yjit + vm_insns_count; - double ratio = retired_in_yjit / total_insns_count; - - fprintf(stderr, "ratio_in_yjit: %9.1f%%\n", ratio * 100); - fprintf(stderr, "avg_len_in_yjit: %10.1f\n", avg_len_in_yjit); - fprintf(stderr, "total_exit_count: %10ld\n", total_exit_count); fprintf(stderr, "most frequent exit op:\n"); + // Print the top-N most frequent exit counts for (int i = 0; i < how_many; i++) { - const char *instruction_name = insn_name(buffer[i].insn); + const char *instruction_name = insn_name(sorted_exit_ops[i].insn); size_t padding = left_pad + longest_insn_len - strlen(instruction_name); for (size_t j = 0; j < padding; j++) { fputc(' ', stderr); } - double percent = 100 * buffer[i].count / (double)total_exit_count; - fprintf(stderr, "%s: %10" PRId64 " (%.1f%%)\n", instruction_name, buffer[i].count, percent); + double percent = 100 * sorted_exit_ops[i].count / (double)total_exit_count; + fprintf(stderr, "%s: %10" PRId64 " (%.1f%%)\n", instruction_name, sorted_exit_ops[i].count, percent); } } @@ -854,16 +857,36 @@ __attribute__((destructor)) https://github.com/ruby/ruby/blob/trunk/yjit_iface.c#L857 static void print_yjit_stats(void) { - if (!rb_yjit_opts.gen_stats) return; + if (!rb_yjit_opts.gen_stats) { + return; + } - const struct insn_count *sorted_exit_ops = sort_insn_count_array(exit_op_count); + // Compute the total exit count + int64_t total_exit_count = calc_total_exit_count(); + + // Number of instructions that finish executing in YJIT. See :count-placement:. + int64_t retired_in_yjit = yjit_runtime_counters.exec_instruction - total_exit_count; + + // Average length of instruction sequences executed by YJIT + double avg_len_in_yjit = (double)retired_in_yjit / total_exit_count; + + // Proportion of instructions that retire in YJIT + int64_t total_insns_count = retired_in_yjit + vm_insns_count; + double ratio = retired_in_yjit / (double)total_insns_count; fprintf(stderr, "compiled_iseq_count: %10" PRId64 "\n", rb_compiled_iseq_count); fprintf(stderr, "inline_code_size: %10d\n", cb->write_pos); fprintf(stderr, "outlined_code_size: %10d\n", ocb->write_pos); + + fprintf(stderr, "total_exit_count: %10" PRId64 "\n", total_exit_count); + fprintf(stderr, "total_insns_count: %10" PRId64 "\n", total_insns_count); fprintf(stderr, "vm_insns_count: %10" PRId64 "\n", vm_insns_count); - fprintf(stderr, "yjit_exec_insns_count: %10" PRId64 "\n", yjit_runtime_counters.exec_instruction); - print_insn_count_buffer(sorted_exit_ops, 10, 4); + fprintf(stderr, "yjit_insns_count: %10" PRId64 "\n", yjit_runtime_counters.exec_instruction); + fprintf(stderr, "ratio_in_yjit: %9.1f%%\n", ratio * 100); + fprintf(stderr, "avg_len_in_yjit: %10.1f\n", avg_len_in_yjit); + + // Print the top-10 most frequent exit ops + print_insn_count_buffer(10, 4); } #endif // if RUBY_DEBUG -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/