summaryrefslogtreecommitdiff
path: root/application-devel
diff options
context:
space:
mode:
authorJan Altenberg <jan@linutronix.de>2014-07-17 15:31:07 +0200
committerJan Altenberg <jan@linutronix.de>2014-07-17 15:31:07 +0200
commit93cb8582cac3c43592e5aa6e8a78e028860d4736 (patch)
treeab4c646ef871927b38e3baa2875956fb9a40d42f /application-devel
parent46bba9d4e8c6dd654af7ad15e7a98a89c46203ac (diff)
Basic introduction to Profiling and code coverage (Gprof, Callgrind, Perf, Gcov)
Diffstat (limited to 'application-devel')
-rw-r--r--application-devel/Kconfig1
-rw-r--r--application-devel/profiling/Kconfig7
-rw-r--r--application-devel/profiling/Makefile1
-rw-r--r--application-devel/profiling/pres_app_profiling_en.tex214
4 files changed, 223 insertions, 0 deletions
diff --git a/application-devel/Kconfig b/application-devel/Kconfig
index e92a974..5a3f4d2 100644
--- a/application-devel/Kconfig
+++ b/application-devel/Kconfig
@@ -11,6 +11,7 @@ if APPLICATION_DEVELOPMENT
source "application-devel/devel-environment/Kconfig"
source "application-devel/compile-tools/Kconfig"
source "application-devel/cross-devel/Kconfig"
+ source "application-devel/profiling/Kconfig"
endif
diff --git a/application-devel/profiling/Kconfig b/application-devel/profiling/Kconfig
new file mode 100644
index 0000000..57c796a
--- /dev/null
+++ b/application-devel/profiling/Kconfig
@@ -0,0 +1,7 @@
+config APPLICATION_PROFILING
+ bool "Application profiling"
+ default y
+ help
+ Howto on profiling and code coverage (gprof / gcov)
+
+
diff --git a/application-devel/profiling/Makefile b/application-devel/profiling/Makefile
new file mode 100644
index 0000000..59482ca
--- /dev/null
+++ b/application-devel/profiling/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_APPLICATION_PROFILING) += pres_app_profiling_en.pdf
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}