From 88ae6dbb0edf5157b76b6d5de251ba1d338f352e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sat, 4 Aug 2018 14:07:34 +0200 Subject: [PATCH] Write the benchmarking part --- report/TODO | 1 + report/report.tex | 61 ++++++++++++++++++++++++++++++++++++++++++++--- shared/report.bib | 26 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/report/TODO b/report/TODO index a906a46..929274f 100644 --- a/report/TODO +++ b/report/TODO @@ -1 +1,2 @@ - Make consistant -ise / -ize (eg. optimize) +- Add references to all my repositories diff --git a/report/report.tex b/report/report.tex index 644b87a..9736b5d 100644 --- a/report/report.tex +++ b/report/report.tex @@ -757,7 +757,7 @@ protocol, and afterwards, a good deal of code reading and coding to get the solution working. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Requirements} +\subsection{Requirements}\label{ssec:bench_req} To provide relevant benchmarks of the \ehelfs{} performance, one must sample at least a few hundreds or thousands of stack unwinding, since a single frame @@ -797,11 +797,66 @@ integrate the sampled data in the end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Benchmarking with \prog{perf}} -\todo{} + +In the context of this internship, the main advantage of \prog{perf} is that it +does a lot of stack unwinding. It also meets all the requirements from +Section~\ref{ssec:bench_req} above: since it stops at regular intervals and +unwinds, the unwindings are evenly distributed \wrt{} the frequency of +execution of the code, which is a natural enough setup for the benchmarks to be +meaningful, while still unwinding from diversified locations, preventing +caching from being be overwhelming. It also has the ability to unwind from +within any function, included functions of linked shared libraries. It can also +be applied to virtually any program, which allows unwinding ``interesting'' +code. + +The program that was chosen for \prog{perf}-benchmarking is +\prog{hackbench}~\cite{hackbenchsrc}. This small program is designed to +stress-test and benchmark the Linux scheduler by spawning processes or threads +that communicate with each other. It has the interest of generating stack +activity, be linked against \prog{libc} and \prog{pthread}, and be very light. + +\medskip + +Interfacing \ehelfs{} with \prog{perf} required, in a first place, to fork +\prog{libunwind} and implement \ehelfs{} support for it. In the process, it +turned out necessary to slightly modify \prog{libunwind}'s interface to add a +parameter to a function, since \prog{libunwind} is made to be agnostic of the +system and process as much as possible, to be able to unwind in any context. +This very restricted information lacked a memory map (a table indicating which +shared object is mapped at which address in memory) in order to use \ehelfs. +Apart from this, the modified version of \prog{libunwind} produced is entirely +compatible with the vanilla version. + +Once this was done, plugging it in \prog{perf} was the matter of a few lines of +code only. The major problem encountered was to understand how \prog{perf} +works. In order to avoid perturbing the traced program, \prog{perf} does not +unwind at runtime, but rather records at regular interval the program's stack, +and all the auxiliary information that is needed to unwind later. This is done +when running \lstbash{perf record}. Then, \lstbash{perf report} unwinds the +stack to analyze it; but at this point of time, the traced process is long +dead, thus any PID-based approach, or any approach using \texttt{/proc} +information will fail. However, as this was the easiest method, this approach +was chosen when implementing the first version of \ehelfs; thus requiring some +code rewriting. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Other explored methods} -\todo{} + +The first approach tried to benchmark was trying to create some specific C code +that would meet the requirements from Section~\ref{ssec:bench_req}, while +calling itself a benchmarking procedure from time to time. This was abandoned +quite fast, because generating C code interesting enough to be unwound turned +out hard, and the generated FDEs invariably ended out uninteresting. It would +also never have met the requirement of unwinding from fairly distributed +locations anyway. + +Another attempt was made using CSmith~\cite{csmith}, a random C code generator +initially made for C compilers random testing. The idea was still to craft an +interesting C program that would unwind on its own frequently, but to integrate +randomly generated C code with CSmith to integrate interesting C snippets that +would generate large enough FDEs and nested calls. This was abandoned as well +as the call graph of a CSmith-generated code is often far too small, and the +CSmith code is notoriously hard to understand and edit. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/shared/report.bib b/shared/report.bib index 020492a..986d4f8 100644 --- a/shared/report.bib +++ b/shared/report.bib @@ -50,3 +50,29 @@ urldate={2018-08-04} } +@online{hackbenchsrc, + title={Hackbench}, + author={Zhang, Yanmin}, + url={https://people.redhat.com/mingo/cfs-scheduler/tools/hackbench.c}, + year={2008} +} + +@inproceedings{csmith, + author = {Xuejun Yang and + Yang Chen and + Eric Eide and + John Regehr}, + title = {Finding and understanding bugs in {C} compilers}, + booktitle = {Proceedings of the 32nd {ACM} {SIGPLAN} Conference on Programming + Language Design and Implementation, {PLDI} 2011, San Jose, CA, USA, + June 4-8, 2011}, + pages = {283--294}, + year = {2011}, + crossref = {DBLP:conf/pldi/2011}, + url = {http://doi.acm.org/10.1145/1993498.1993532}, + doi = {10.1145/1993498.1993532}, + timestamp = {Mon, 05 Jun 2017 12:39:37 +0200}, + biburl = {https://dblp.org/rec/bib/conf/pldi/YangCER11}, + bibsource = {dblp computer science bibliography, https://dblp.org} +} +