From: Nicholas Nethercote Date: Mon, 13 May 2002 20:27:54 +0000 (+0000) Subject: Expanded --sort option to take threshold args with the event names. Lets you X-Git-Tag: svn/VALGRIND_1_0_3~195 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8cbe9082c5409fd66f65a09087afe89eeac36b9b;p=thirdparty%2Fvalgrind.git Expanded --sort option to take threshold args with the event names. Lets you do things like "show functions covering 99% of all D2mr events *and* 99% of all D2mw events" - before you could only choose the threshold for one. Useful for me, but probably no-one else. Still mentioned it in the docs, though. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@269 --- diff --git a/cachegrind/cg_annotate.in b/cachegrind/cg_annotate.in index eb7e5dd3ed..30cc049ecb 100644 --- a/cachegrind/cg_annotate.in +++ b/cachegrind/cg_annotate.in @@ -112,15 +112,18 @@ my @show_order; my @sort_events; # Map from @sort_events indices to @events indices, eg. (3,2). Same idea as -# for @show_order +# for @show_order. my @sort_order; -# Threshold; whatever event is the primary sort, we print out functions -# representing more than this proportion of 'event' events. -my $threshold = 99; +# Thresholds, one for each sort event (or default to 1 if no sort events +# specified). We print out functions and do auto-annotations until we've +# handled this proportion of all the events thresholded. +my @thresholds; + +my $default_threshold = 99; # If on, automatically annotates all files that are involved in getting over -# the threshold count of the primary sort event. +# all the threshold counts. my $auto_annotate = 0; # Number of lines to show around each annotated line. @@ -145,7 +148,7 @@ usage: vg_annotate [options] [source-files] --show=A,B,C only show figures for events A,B,C [all] --sort=A,B,C sort columns by events A,B,C [event column order] --threshold=<0--100> percentage of counts (of primary sort event) we - are interested in [$threshold%] + are interested in [$default_threshold%] --auto=yes|no annotate all source files containing functions that helped reach the event count threshold [no] --context=N print N lines of context before and after @@ -184,13 +187,22 @@ sub process_cmd_line() # --sort=A,B,C } elsif ($arg =~ /^--sort=(.*)$/) { @sort_events = split(/,/, $1); + foreach my $i (0 .. scalar @sort_events - 1) { + if ($sort_events[$i] =~#/.*:(\d+)$/) { + /.*:([\d\.]+)%?$/) { + my $th = $1; + ($th >= 0 && $th <= 100) or die($usage); + $sort_events[$i] =~ s/:.*//; + $thresholds[$i] = $th; + } else { + $thresholds[$i] = 0; + } + } # --threshold=X (tolerates a trailing '%') } elsif ($arg =~ /^--threshold=([\d\.]+)%?$/) { - $threshold = $1; - if ($threshold < 0 || $threshold > 100) { - die($usage); - } + $thresholds[0] = $1; + ($1 >= 0 && $1 <= 100) or die($usage); # --auto=yes|no } elsif ($arg =~ /^--auto=(yes|no)$/) { @@ -242,8 +254,9 @@ sub max ($$) # 1. If $a2->[$i] is undefined, it defaults to 0 which is what we want; we turn # off warnings to allow this. This makes things about 10% faster than # checking for definedness ourselves. -# 2. We don't add a ".", even though it's value is 0, because we don't want to -# make an $a2->[$i] that is undef become 0 unnecessarily. +# 2. We don't add an undefined count or a ".", even though it's value is 0, +# because we don't want to make an $a2->[$i] that is undef become 0 +# unnecessarily. sub add_array_a_to_b ($$) { my ($a1, $a2) = @_; @@ -251,7 +264,7 @@ sub add_array_a_to_b ($$) my $n = max(scalar @$a1, scalar @$a2); $^W = 0; foreach my $i (0 .. $n-1) { - $a2->[$i] += $a1->[$i] if ("." ne $a1->[$i]); + $a2->[$i] += $a1->[$i] if (defined $a1->[$i] && "." ne $a1->[$i]); } $^W = 1; } @@ -331,6 +344,15 @@ sub read_input_file() push(@sort_order, $events{$sort_event}); } + # If no --threshold args give, default to 99% for the primary sort event, + # and 0% for the rest. + if (not @thresholds) { + foreach my $e (@sort_order) { + push(@thresholds, 0); + } + $thresholds[0] = $default_threshold; + } + my $curr_file; my $curr_fn; my $curr_name; @@ -424,7 +446,7 @@ sub print_options () print("Events recorded: @events\n"); print("Events shown: @show_events\n"); print("Event sort order: @sort_events\n"); - print("Threshold: $threshold%\n"); + print("Thresholds: @thresholds\n"); my @include_dirs2 = @include_dirs; # copy @include_dirs shift(@include_dirs2); # remove "" entry, which is always the first @@ -534,7 +556,7 @@ sub print_events ($) # Prints summary and function totals (with separate column widths, so that # function names aren't pushed over unnecessarily by huge summary figures). # Also returns a hash containing all the files that are involved in getting the -# events count above the threshold (ie. all the interesting ones). +# events count above the thresholds (ie. all the interesting ones). sub print_summary_and_fn_totals () { my @fn_fullnames = keys %fn_totals; @@ -564,29 +586,43 @@ sub print_summary_and_fn_totals () mycmp($fn_totals{$a}, $fn_totals{$b}) } @fn_fullnames; - # The thresholded event is the one that is the primary sort event. + + # Assertion + (scalar @sort_order == scalar @thresholds) or + die("sort_order length != thresholds length:\n", + " @sort_order\n @thresholds\n"); + my $threshold_files = {}; - my $threshold_event_index = $sort_order[0]; - my $threshold_total = $summary_CC->[$threshold_event_index]; - my $curr_total = 0; + # @curr_totals has the same shape as @sort_order and @thresholds + my @curr_totals = (); + foreach my $e (@thresholds) { + push(@curr_totals, 0); + } # Print functions, stopping when the threshold has been reached. foreach my $fn_name (@fn_fullnames) { - # Stop when we've reached the threshold - last if ($curr_total * 100 / $threshold_total >= $threshold); + # Stop when we've reached all the thresholds + my $reached_all_thresholds = 1; + foreach my $i (scalar @thresholds - 1) { + my $prop = $curr_totals[$i] * 100 / $summary_CC->[$sort_order[$i]]; + $reached_all_thresholds &= ($prop >= $thresholds[$i]); + } + last if $reached_all_thresholds; # Print function results my $fn_CC = $fn_totals{$fn_name}; print_CC($fn_CC, $fn_CC_col_widths); print(" $fn_name\n"); - # Update the threshold counting + # Update the threshold counts my $filename = $fn_name; $filename =~ s/:.+$//; # remove function name $threshold_files->{$filename} = 1; - $curr_total += $fn_CC->[$threshold_event_index] - if (defined $fn_CC->[$threshold_event_index]); + foreach my $i (0 .. scalar @sort_order - 1) { + $curr_totals[$i] += $fn_CC->[$sort_order[$i]] + if (defined $fn_CC->[$sort_order[$i]]); + } } print("\n"); diff --git a/cachegrind/docs/manual.html b/cachegrind/docs/manual.html index 24f0d2b972..dc66721359 100644 --- a/cachegrind/docs/manual.html +++ b/cachegrind/docs/manual.html @@ -2462,8 +2462,16 @@ programs.
  • --threshold=X [default: 99%]

    Sets the threshold for the function-by-function summary. Functions are - shown that account for more than X% of all the primary sort events. If - auto-annotating, also affects which files are annotated.

  • + shown that account for more than X% of the primary sort event. If + auto-annotating, also affects which files are annotated. + + Note: thresholds can be set for more than one of the events by appending + any events for the --sort option with a colon and a number + (no spaces, though). E.g. if you want to see the functions that cover + 99% of L2 read misses and 99% of L2 write misses, use this option: + +

    --sort=D2mr:99,D2mw:99
    +

  • --auto=no [default]
    --auto=yes

    @@ -2568,13 +2576,21 @@ Some odd things that can occur during annotation: number. Valgrind can handle some files with more than 65,535 lines correctly by making some guesses to identify line number overflows. But some cases are beyond it, in which case you'll get a warning message - explaining that annotations for the file might be incorrect. + explaining that annotations for the file might be incorrect.

    +

  • + +
  • If you compile some files with -g and some without, some + events that take place in a file without debug info could be attributed + to the last line of a file with debug info (whichever one gets placed + before the non-debug-info file in the executable).

  • +This list looks long, but these cases should be fairly rare.

    + Note: stabs is not an easy format to read. If you come across bizarre annotations that look like might be caused by a bug in the stabs reader, -please let us know. +please let us know.

    7.11  Accuracy

    @@ -2594,6 +2610,10 @@ Valgrind's cache profiling has a number of shortcomings:
  • It doesn't account for cache misses not visible at the instruction level, eg. those arising from TLB misses, or speculative execution.
  • +

  • Valgrind's custom malloc() will allocate memory in different + ways to the standard malloc(), which could warp the results. +
  • +

  • The instructions bts, btr and btc will incorrectly be counted as doing a data read if both the arguments are registers, eg: diff --git a/coregrind/docs/manual.html b/coregrind/docs/manual.html index 24f0d2b972..dc66721359 100644 --- a/coregrind/docs/manual.html +++ b/coregrind/docs/manual.html @@ -2462,8 +2462,16 @@ programs.
  • --threshold=X [default: 99%]

    Sets the threshold for the function-by-function summary. Functions are - shown that account for more than X% of all the primary sort events. If - auto-annotating, also affects which files are annotated.

  • + shown that account for more than X% of the primary sort event. If + auto-annotating, also affects which files are annotated. + + Note: thresholds can be set for more than one of the events by appending + any events for the --sort option with a colon and a number + (no spaces, though). E.g. if you want to see the functions that cover + 99% of L2 read misses and 99% of L2 write misses, use this option: + +

    --sort=D2mr:99,D2mw:99
    +

  • --auto=no [default]
    --auto=yes

    @@ -2568,13 +2576,21 @@ Some odd things that can occur during annotation: number. Valgrind can handle some files with more than 65,535 lines correctly by making some guesses to identify line number overflows. But some cases are beyond it, in which case you'll get a warning message - explaining that annotations for the file might be incorrect. + explaining that annotations for the file might be incorrect.

    +

  • + +
  • If you compile some files with -g and some without, some + events that take place in a file without debug info could be attributed + to the last line of a file with debug info (whichever one gets placed + before the non-debug-info file in the executable).

  • +This list looks long, but these cases should be fairly rare.

    + Note: stabs is not an easy format to read. If you come across bizarre annotations that look like might be caused by a bug in the stabs reader, -please let us know. +please let us know.

    7.11  Accuracy

    @@ -2594,6 +2610,10 @@ Valgrind's cache profiling has a number of shortcomings:
  • It doesn't account for cache misses not visible at the instruction level, eg. those arising from TLB misses, or speculative execution.
  • +

  • Valgrind's custom malloc() will allocate memory in different + ways to the standard malloc(), which could warp the results. +
  • +

  • The instructions bts, btr and btc will incorrectly be counted as doing a data read if both the arguments are registers, eg: diff --git a/docs/manual.html b/docs/manual.html index 24f0d2b972..dc66721359 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -2462,8 +2462,16 @@ programs.
  • --threshold=X [default: 99%]

    Sets the threshold for the function-by-function summary. Functions are - shown that account for more than X% of all the primary sort events. If - auto-annotating, also affects which files are annotated.

  • + shown that account for more than X% of the primary sort event. If + auto-annotating, also affects which files are annotated. + + Note: thresholds can be set for more than one of the events by appending + any events for the --sort option with a colon and a number + (no spaces, though). E.g. if you want to see the functions that cover + 99% of L2 read misses and 99% of L2 write misses, use this option: + +

    --sort=D2mr:99,D2mw:99
    +

  • --auto=no [default]
    --auto=yes

    @@ -2568,13 +2576,21 @@ Some odd things that can occur during annotation: number. Valgrind can handle some files with more than 65,535 lines correctly by making some guesses to identify line number overflows. But some cases are beyond it, in which case you'll get a warning message - explaining that annotations for the file might be incorrect. + explaining that annotations for the file might be incorrect.

    +

  • + +
  • If you compile some files with -g and some without, some + events that take place in a file without debug info could be attributed + to the last line of a file with debug info (whichever one gets placed + before the non-debug-info file in the executable).

  • +This list looks long, but these cases should be fairly rare.

    + Note: stabs is not an easy format to read. If you come across bizarre annotations that look like might be caused by a bug in the stabs reader, -please let us know. +please let us know.

    7.11  Accuracy

    @@ -2594,6 +2610,10 @@ Valgrind's cache profiling has a number of shortcomings:
  • It doesn't account for cache misses not visible at the instruction level, eg. those arising from TLB misses, or speculative execution.
  • +

  • Valgrind's custom malloc() will allocate memory in different + ways to the standard malloc(), which could warp the results. +
  • +

  • The instructions bts, btr and btc will incorrectly be counted as doing a data read if both the arguments are registers, eg: diff --git a/memcheck/docs/manual.html b/memcheck/docs/manual.html index 24f0d2b972..dc66721359 100644 --- a/memcheck/docs/manual.html +++ b/memcheck/docs/manual.html @@ -2462,8 +2462,16 @@ programs.
  • --threshold=X [default: 99%]

    Sets the threshold for the function-by-function summary. Functions are - shown that account for more than X% of all the primary sort events. If - auto-annotating, also affects which files are annotated.

  • + shown that account for more than X% of the primary sort event. If + auto-annotating, also affects which files are annotated. + + Note: thresholds can be set for more than one of the events by appending + any events for the --sort option with a colon and a number + (no spaces, though). E.g. if you want to see the functions that cover + 99% of L2 read misses and 99% of L2 write misses, use this option: + +

    --sort=D2mr:99,D2mw:99
    +

  • --auto=no [default]
    --auto=yes

    @@ -2568,13 +2576,21 @@ Some odd things that can occur during annotation: number. Valgrind can handle some files with more than 65,535 lines correctly by making some guesses to identify line number overflows. But some cases are beyond it, in which case you'll get a warning message - explaining that annotations for the file might be incorrect. + explaining that annotations for the file might be incorrect.

    +

  • + +
  • If you compile some files with -g and some without, some + events that take place in a file without debug info could be attributed + to the last line of a file with debug info (whichever one gets placed + before the non-debug-info file in the executable).

  • +This list looks long, but these cases should be fairly rare.

    + Note: stabs is not an easy format to read. If you come across bizarre annotations that look like might be caused by a bug in the stabs reader, -please let us know. +please let us know.

    7.11  Accuracy

    @@ -2594,6 +2610,10 @@ Valgrind's cache profiling has a number of shortcomings:
  • It doesn't account for cache misses not visible at the instruction level, eg. those arising from TLB misses, or speculative execution.
  • +

  • Valgrind's custom malloc() will allocate memory in different + ways to the standard malloc(), which could warp the results. +
  • +

  • The instructions bts, btr and btc will incorrectly be counted as doing a data read if both the arguments are registers, eg: diff --git a/vg_annotate.in b/vg_annotate.in index eb7e5dd3ed..30cc049ecb 100644 --- a/vg_annotate.in +++ b/vg_annotate.in @@ -112,15 +112,18 @@ my @show_order; my @sort_events; # Map from @sort_events indices to @events indices, eg. (3,2). Same idea as -# for @show_order +# for @show_order. my @sort_order; -# Threshold; whatever event is the primary sort, we print out functions -# representing more than this proportion of 'event' events. -my $threshold = 99; +# Thresholds, one for each sort event (or default to 1 if no sort events +# specified). We print out functions and do auto-annotations until we've +# handled this proportion of all the events thresholded. +my @thresholds; + +my $default_threshold = 99; # If on, automatically annotates all files that are involved in getting over -# the threshold count of the primary sort event. +# all the threshold counts. my $auto_annotate = 0; # Number of lines to show around each annotated line. @@ -145,7 +148,7 @@ usage: vg_annotate [options] [source-files] --show=A,B,C only show figures for events A,B,C [all] --sort=A,B,C sort columns by events A,B,C [event column order] --threshold=<0--100> percentage of counts (of primary sort event) we - are interested in [$threshold%] + are interested in [$default_threshold%] --auto=yes|no annotate all source files containing functions that helped reach the event count threshold [no] --context=N print N lines of context before and after @@ -184,13 +187,22 @@ sub process_cmd_line() # --sort=A,B,C } elsif ($arg =~ /^--sort=(.*)$/) { @sort_events = split(/,/, $1); + foreach my $i (0 .. scalar @sort_events - 1) { + if ($sort_events[$i] =~#/.*:(\d+)$/) { + /.*:([\d\.]+)%?$/) { + my $th = $1; + ($th >= 0 && $th <= 100) or die($usage); + $sort_events[$i] =~ s/:.*//; + $thresholds[$i] = $th; + } else { + $thresholds[$i] = 0; + } + } # --threshold=X (tolerates a trailing '%') } elsif ($arg =~ /^--threshold=([\d\.]+)%?$/) { - $threshold = $1; - if ($threshold < 0 || $threshold > 100) { - die($usage); - } + $thresholds[0] = $1; + ($1 >= 0 && $1 <= 100) or die($usage); # --auto=yes|no } elsif ($arg =~ /^--auto=(yes|no)$/) { @@ -242,8 +254,9 @@ sub max ($$) # 1. If $a2->[$i] is undefined, it defaults to 0 which is what we want; we turn # off warnings to allow this. This makes things about 10% faster than # checking for definedness ourselves. -# 2. We don't add a ".", even though it's value is 0, because we don't want to -# make an $a2->[$i] that is undef become 0 unnecessarily. +# 2. We don't add an undefined count or a ".", even though it's value is 0, +# because we don't want to make an $a2->[$i] that is undef become 0 +# unnecessarily. sub add_array_a_to_b ($$) { my ($a1, $a2) = @_; @@ -251,7 +264,7 @@ sub add_array_a_to_b ($$) my $n = max(scalar @$a1, scalar @$a2); $^W = 0; foreach my $i (0 .. $n-1) { - $a2->[$i] += $a1->[$i] if ("." ne $a1->[$i]); + $a2->[$i] += $a1->[$i] if (defined $a1->[$i] && "." ne $a1->[$i]); } $^W = 1; } @@ -331,6 +344,15 @@ sub read_input_file() push(@sort_order, $events{$sort_event}); } + # If no --threshold args give, default to 99% for the primary sort event, + # and 0% for the rest. + if (not @thresholds) { + foreach my $e (@sort_order) { + push(@thresholds, 0); + } + $thresholds[0] = $default_threshold; + } + my $curr_file; my $curr_fn; my $curr_name; @@ -424,7 +446,7 @@ sub print_options () print("Events recorded: @events\n"); print("Events shown: @show_events\n"); print("Event sort order: @sort_events\n"); - print("Threshold: $threshold%\n"); + print("Thresholds: @thresholds\n"); my @include_dirs2 = @include_dirs; # copy @include_dirs shift(@include_dirs2); # remove "" entry, which is always the first @@ -534,7 +556,7 @@ sub print_events ($) # Prints summary and function totals (with separate column widths, so that # function names aren't pushed over unnecessarily by huge summary figures). # Also returns a hash containing all the files that are involved in getting the -# events count above the threshold (ie. all the interesting ones). +# events count above the thresholds (ie. all the interesting ones). sub print_summary_and_fn_totals () { my @fn_fullnames = keys %fn_totals; @@ -564,29 +586,43 @@ sub print_summary_and_fn_totals () mycmp($fn_totals{$a}, $fn_totals{$b}) } @fn_fullnames; - # The thresholded event is the one that is the primary sort event. + + # Assertion + (scalar @sort_order == scalar @thresholds) or + die("sort_order length != thresholds length:\n", + " @sort_order\n @thresholds\n"); + my $threshold_files = {}; - my $threshold_event_index = $sort_order[0]; - my $threshold_total = $summary_CC->[$threshold_event_index]; - my $curr_total = 0; + # @curr_totals has the same shape as @sort_order and @thresholds + my @curr_totals = (); + foreach my $e (@thresholds) { + push(@curr_totals, 0); + } # Print functions, stopping when the threshold has been reached. foreach my $fn_name (@fn_fullnames) { - # Stop when we've reached the threshold - last if ($curr_total * 100 / $threshold_total >= $threshold); + # Stop when we've reached all the thresholds + my $reached_all_thresholds = 1; + foreach my $i (scalar @thresholds - 1) { + my $prop = $curr_totals[$i] * 100 / $summary_CC->[$sort_order[$i]]; + $reached_all_thresholds &= ($prop >= $thresholds[$i]); + } + last if $reached_all_thresholds; # Print function results my $fn_CC = $fn_totals{$fn_name}; print_CC($fn_CC, $fn_CC_col_widths); print(" $fn_name\n"); - # Update the threshold counting + # Update the threshold counts my $filename = $fn_name; $filename =~ s/:.+$//; # remove function name $threshold_files->{$filename} = 1; - $curr_total += $fn_CC->[$threshold_event_index] - if (defined $fn_CC->[$threshold_event_index]); + foreach my $i (0 .. scalar @sort_order - 1) { + $curr_totals[$i] += $fn_CC->[$sort_order[$i]] + if (defined $fn_CC->[$sort_order[$i]]); + } } print("\n");