ftrace: fix stddev calculation
PATCH 1/1 ftrace: fix stddev calculation
When FUNCTION_GRAPH_TRACER is enabled, ftrace can profile kernel functions and print basic statistics about them. Unfortunately, running stddev calculation is wrong. This patch corrects it implementing Welford’s method:
s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) .
Signed-off-by Juri Lelli <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Ingo Molnar <[email protected]>
--- kernel/trace/ftrace.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
kernel/trace/ftrace.c +8 -2
@@ -622,12 +622,18 @@ static int function_stat_show(struct seq_file *m, void *v)if (rec->counter <=1 ) stddev =0 ;else { - stddev = rec->time_squared - rec->counter * avg * avg; +/* +* Apply Welford's method: +* s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) +*/ + stddev = rec->counter * rec->time_squared - + rec->time * rec->time; +/* * Divide only 1000 for ns^2 -> us^2 conversion. * trace_print_graph_duration will divide 1000 again. */ -do_div (stddev, (rec->counter -1 ) *1000 ); +do_div (stddev, rec->counter * (rec->counter -1 ) *1000 ); }trace_seq_init (&s);
Signature · 1 line
1.7.9.5
Steven Rostedt
maintainerQuoted 7 lines · Juri Lelli
When
FUNCTION_GRAPH_TRACERis enabled, ftrace can profile kernel functions and print basic statistics about them. Unfortunately, running stddev calculation is wrong. This patch corrects it implementing Welford’s method:s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) .Signed-off-by Juri Lelli <[email protected]>
I pulled this into my 3.11 queue. Thanks!
-- Steve
Quoted 32 lines
Cc Steven Rostedt <[email protected]>Cc Frederic Weisbecker <[email protected]>Cc Ingo Molnar <[email protected]>--- kernel/trace/ftrace.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)kernel/trace/ftrace.c +8
-2@@ -622,12 +622,18 @@ static int function_stat_show(struct seq_file *m, void *v)if (rec->counter <=1 ) stddev =0 ;else { - stddev = rec->time_squared - rec->counter * avg * avg; +/* +* Apply Welford's method: +* s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) +*/ + stddev = rec->counter * rec->time_squared - + rec->time * rec->time; +/* * Divide only 1000 for ns^2 -> us^2 conversion. * trace_print_graph_duration will divide 1000 again. */ -do_div (stddev, (rec->counter -1 ) *1000 ); +do_div (stddev, rec->counter * (rec->counter -1 ) *1000 ); }trace_seq_init (&s);