From 93cb8582cac3c43592e5aa6e8a78e028860d4736 Mon Sep 17 00:00:00 2001
From: Jan Altenberg <jan@linutronix.de>
Date: Thu, 17 Jul 2014 15:31:07 +0200
Subject: Basic introduction to Profiling and code coverage (Gprof, Callgrind,
 Perf, Gcov)

---
 .../profiling/pres_app_profiling_en.tex            | 214 +++++++++++++++++++++
 1 file changed, 214 insertions(+)
 create mode 100644 application-devel/profiling/pres_app_profiling_en.tex

(limited to 'application-devel/profiling/pres_app_profiling_en.tex')

diff --git a/application-devel/profiling/pres_app_profiling_en.tex b/application-devel/profiling/pres_app_profiling_en.tex
new file mode 100644
index 0000000..259d176
--- /dev/null
+++ b/application-devel/profiling/pres_app_profiling_en.tex
@@ -0,0 +1,214 @@
+\input{configpres}
+
+\subsection{Profiling}
+
+\title{\lq Profiling and code coverage\rq}
+\maketitle
+
+\begin{frame}
+\frametitle{Overview}
+\tableofcontents
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+Compile AND link with profile information:
+\begin{verbatim}
+# Compile and link in one go
+
+gcc -Wall -pg -o gprof_test gprof_test.c
+
+# or
+
+gcc -Wall -pg -o gprof_test.o gprof_test.c
+gcc -Wall -pg -o gprof_test gprof_test.o
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+Run the program:
+\begin{verbatim}
+# Run the program
+
+$ ./gprof_test
+
+# that should produce a gmon.out
+
+$ ls gmon.out
+gmon.out
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+\begin{alertblock}{When and where will gmon.out be written?}
+gmon.out will be written right before your application exits.
+It will be written to the directory where your application is
+being executed.
+\end{alertblock}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+Specifiying a custom filename for gmon.out:
+\begin{verbatim}
+export GMON_OUT_PREFIX=custom_gmon
+
+# The resulting file will be called ${GMON_OUT_PREFIX}.PID
+# (while PID is the process ID of the profiled process)
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+Run the program:
+\begin{verbatim}
+# Analyze the result
+
+$ gprof gprof_test gmon.out > analysis.txt
+
+$ less analysis.txt
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+\begin{verbatim}
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+  %   cumulative   self              self     total
+ time   seconds   seconds    calls  ms/call  ms/call  name
+ 40.00      0.04     0.04        1    40.00    40.00  f2
+ 30.00      0.07     0.03        1    30.00    30.00  f1
+ 30.00      0.10     0.03                             main
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+\begin{verbatim}
+             Call graph (explanation follows)
+
+granularity: each sample hit covers 4 byte(s) for 10.00% of 0.10 seconds
+
+index % time    self  children    called     name
+                                                 <spontaneous>
+[1]    100.0    0.03    0.07                 main [1]
+                0.04    0.00       1/1           f2 [2]
+                0.03    0.00       1/1           f1 [3]
+-----------------------------------------------
+                0.04    0.00       1/1           main [1]
+[2]     40.0    0.04    0.00       1         f2 [2]
+-----------------------------------------------
+                0.03    0.00       1/1           main [1]
+[3]     30.0    0.03    0.00       1         f1 [3]
+-----------------------------------------------
+
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Using gprof}
+Format gprof output
+\begin{verbatim}
+# Suppress printing of statically declared functions
+
+gprof -a gprof_test gmon.out
+gprof --no-static gprof_test gmon.out
+
+# Don't be verbose
+
+gprof -b gprof_test gmon.out
+gprof --brief gprof_test gmon.out
+
+# Only print the flat profile
+
+gprof -p gprof_test gmon.out
+gprof --flat-profile gprof_test gmon.out
+
+# DON'T print the flat profile
+
+gprof -P gprof_test gmon.out
+gprof --no-flat-profile gprof_test gmon.out
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Callgrind}
+\begin{verbatim}
+$ gcc -Wall -o gprof_test gprof_test.c
+$ valgrind --tool=callgrind ./gprof_test
+
+$ ls callgrind*
+callgrind.out.4804
+
+$ callgrind_annotate callgrind.out.4804 gprof_test
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Callgrind and pthreads}
+\begin{verbatim}
+$ gcc -Wall -o gprof_test gprof_test.c
+$ valgrind --tool=callgrind --separate-threads=yes ./gprof_test
+
+$ ls callgrind*
+callgrind.out.4804-01 callgrind.out.4804-02
+
+$ callgrind_annotate callgrind.out.4804-01 gprof_test
+$ callgrind_annotate callgrind.out.4804-02 gprof_test
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Profiling with perf}
+\begin{verbatim}
+$ perf record ./pthread_example
+
+$ ls perf.data
+perf.data
+
+$ perf report
+\end{verbatim}
+\end{frame}
+
+\subsection{Code coverage}
+
+\begin{frame}[fragile]
+\frametitle{Code coverage with gcov}
+\begin{verbatim}
+$ gcc -Wall -fprofile-arcs -ftest-coverage -o gcov_test gcov_test.c
+
+$ ./gcov_test
+
+$ gcov gcov_test.c 
+File 'gcov_test.c'
+Lines executed:100.00% of 9
+gcov_test.c:creating 'gcov_test.c.gcov'
+
+\end{verbatim}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Code coverage with gcov}
+\begin{verbatim}
+$ cat gcov_test.c.gcov
+[...]
+        1:    3:int main (void)
+        -:    4:{
+        -:    5:        int i;
+        -:    6:
+      100:    7:        for (i = 1; i < 100; i++) {
+       99:    8:                if (i % 2 == 0)
+       49:    9:                        printf("A");
+       99:   10:                if (i % 3 == 0)
+       33:   11:                        printf("B");
+       99:   12:                if (i % 4 == 0)
+       24:   13:                        printf("C");
+        -:   14:        }
+[...]
+\end{verbatim}
+\end{frame}
+\input{tailpres}
-- 
cgit v1.2.3

