Add spacial bench and FDE size distribution

This commit is contained in:
Théophile Bastian 2018-08-04 20:58:11 +02:00
parent ebedb94dbd
commit 74b8142d34
4 changed files with 150 additions and 9 deletions

View file

@ -0,0 +1,51 @@
lines,proportion
1,0.23499301373163092
2,0.017110093953264273
3,0.07736352686099734
4,0.056643700313177545
5,0.03385015658877379
6,0.03386942905324018
7,0.04987713803902674
8,0.0671876656227415
9,0.008098289568778607
10,0.033187183811129846
11,0.04311443025776921
12,0.07292700554083353
13,0.005184292941459889
14,0.0267906528547338
15,0.017582269332690918
16,0.11287304264032763
17,0.01497277764394122
18,0.0167882437966755
19,0.00454444712117562
20,0.013413635268609973
21,0.00499927728258251
22,0.001603469043603951
23,0.007791857383762949
24,0.01650879306191279
25,0.002752107925801012
26,0.00184822934232715
27,0.001376053962900506
28,0.0025921464707299446
29,0.001821247892074199
30,0.0021218983377499397
31,0.0018925560105998555
32,0.003746567092266924
33,0.0007882437966754999
34,0.0008653336545410745
35,0.0006649000240905806
36,0.00109082148879788
37,0.0005839556733317273
38,0.0005068658154661527
39,0.0006109371235846784
40,0.0015591423753312456
41,0.000439412189833775
42,0.0004914478438930378
43,0.0003257046494820525
44,0.0005916646591182848
45,0.00028330522765598654
46,0.0004586846543001686
47,0.00034112262105516744
48,0.00045290291496025056
49,0.00024861479161647796
50,0.00027174174897615035
1 lines proportion
2 1 0.23499301373163092
3 2 0.017110093953264273
4 3 0.07736352686099734
5 4 0.056643700313177545
6 5 0.03385015658877379
7 6 0.03386942905324018
8 7 0.04987713803902674
9 8 0.0671876656227415
10 9 0.008098289568778607
11 10 0.033187183811129846
12 11 0.04311443025776921
13 12 0.07292700554083353
14 13 0.005184292941459889
15 14 0.0267906528547338
16 15 0.017582269332690918
17 16 0.11287304264032763
18 17 0.01497277764394122
19 18 0.0167882437966755
20 19 0.00454444712117562
21 20 0.013413635268609973
22 21 0.00499927728258251
23 22 0.001603469043603951
24 23 0.007791857383762949
25 24 0.01650879306191279
26 25 0.002752107925801012
27 26 0.00184822934232715
28 27 0.001376053962900506
29 28 0.0025921464707299446
30 29 0.001821247892074199
31 30 0.0021218983377499397
32 31 0.0018925560105998555
33 32 0.003746567092266924
34 33 0.0007882437966754999
35 34 0.0008653336545410745
36 35 0.0006649000240905806
37 36 0.00109082148879788
38 37 0.0005839556733317273
39 38 0.0005068658154661527
40 39 0.0006109371235846784
41 40 0.0015591423753312456
42 41 0.000439412189833775
43 42 0.0004914478438930378
44 43 0.0003257046494820525
45 44 0.0005916646591182848
46 45 0.00028330522765598654
47 46 0.0004586846543001686
48 47 0.00034112262105516744
49 48 0.00045290291496025056
50 49 0.00024861479161647796
51 50 0.00027174174897615035

View file

@ -135,10 +135,9 @@ In most cases of everyday's life, a slow stack unwinding is not a problem, or
even an annoyance. Yet, having a 25 times speed-up on stack unwinding-heavy
tasks, such as profiling, can be really useful to profile heavy programs,
particularly if one wants to profile many times in order to analyze the impact
of multiple changes. It can also be useful for exception-heavy
programs~\qtodo{cite Stephen's software?}. Thus, it might be interesting to
implement a more stable version, and try to interface it cleanly with
mainstream tools, such as \prog{perf}.
of multiple changes. It can also be useful for exception-heavy programs. Thus,
it might be interesting to implement a more stable version, and try to
interface it cleanly with mainstream tools, such as \prog{perf}.
Another question worth exploring might be whether it is possible to shrink even
more the original DWARF unwinding data, which would be stored in a format not

View file

@ -18,6 +18,7 @@ Under supervision of Francesco Zappa-Nardelli\\
\usepackage{makecell}
\usepackage{booktabs}
\usepackage{wrapfig}
\usepackage{pgfplots}
%\usepackage[backend=biber,style=alphabetic]{biblatex}
\usepackage[backend=biber]{biblatex}
@ -194,6 +195,12 @@ particularly if a lot of exceptions are thrown and caught far away in their
call path. In the former, profiling \emph{is} performance-heavy and often quite
slow when analyzing large programs anyway.
One of the causes that inspired this internship were also Stephen Kell's
\prog{libcrunch}~\cite{kell2016libcrunch}, which makes a heavy use of stack
unwinding through \prog{libunwind} and was forced to force \prog{gcc} to use a
frame pointer (\reg{rbp}) everywhere through \lstbash{-fno-omit-frame-pointer}
in order to mitigate the slowness.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{DWARF format}
@ -291,7 +298,40 @@ unwinding process.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{How big are FDEs?}
\todo{}
\begin{figure}[h]
\centering
\begin{tikzpicture}
\begin{axis}[
width=0.9\linewidth, height=4cm,
grid=major,
grid style={dashed,gray!30},
xlabel=FDE row count,
ylabel=Proportion,
%legend style={at={(0.5,-0.2)},anchor=north},
xtick distance=5,
ybar, %added here
]
\addplot[blue,fill] table[x=lines,y=proportion, col sep=comma]
{data/fde_line_count.csv};
\end{axis}
\end{tikzpicture}
\caption{FDE line count density}\label{fig:fde_line_density}
\end{figure}
Since evaluating an \lstc{.eh_frame} FDE entry is, as seen in the previous
section, roughly linear in time in its rows number, we must wonder what is the
distribution of FDE rows count. The histogram in
Figure~\ref{fig:fde_line_density} was generated on a random sample of around
2000 ELF files present on an ArchLinux system.
Most of the FDEs seem to be quite small, which only reflects that most
functions found in the wild are relatively small and do not particularly
allocate many times on the stack. Yet, the median value is at $8$ rows per FDE,
and the average is at $9.7$, which is already not that fast to unwind. Values
up to $50$ are not that uncommon, given some commonly used functions have such
large FDEs, and often end up in the call stack.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Unwinding state-of-the-art}
@ -312,7 +352,7 @@ the relevant FDE from its start, until it finds the row it was seeking.
\section{DWARF semantics}\label{sec:semantics}
We will now define semantics covering most of the operations used for
CFI\footnote{To be defined elsewhere in the report} described in the DWARF
CFI\todo{To be defined elsewhere in the report} described in the DWARF
standard~\cite{dwarf5std}, with the exception of DWARF expressions. These are
not exhaustively treated because they are quite rich and would take a lot of
time and space to formalize, and in the meantime are only seldom used (see the
@ -375,7 +415,7 @@ operand~--- are irrelevant and will be eluded.
row. This is \emph{not implemented in this semantics} for simplicity
and brevity (we would have to introduce CIE (preamble) and FDE (body)
independently). This is also not much used in actual ELF
files\footnote{TODO: refer to stats}.
files\todo{refer to stats}.
\item{} \dwcfa{remember\_state()}~:
push the state of all the registers of this row on an implicit stack
\item{} \dwcfa{restore\_state()}~:
@ -715,7 +755,7 @@ the original program size.
\todo{more in-depth analysis?}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Space optimization}
\subsection{Space optimization}\label{ssec:space_optim}
A lot of small space optimizations, such as filtering out empty FDEs, merging
together the rows that are equivalent on all the registers kept, etc.\ were
@ -923,7 +963,46 @@ seconds (using only a single core).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Measured compactness}\label{ssec:results_size}
\todo{}
A first measure of compactness was made in this report for one of the earliest
working versions in Table~\ref{table:basic_eh_elf_space}.
The same data, generated for the latest version of \ehelfs, can be seen in
Table~\ref{table:bench_space}.
The effect of the outlining mentioned in Section~\ref{ssec:space_optim} is
particularly visible in this table: \prog{hackbench} has a significantly bigger
growth than the other shared objects. This is because \prog{hackbench} has a
way smaller \lstc{.eh_frame}, thus, the outlined data is reused only a few
times, compared to \eg{} \prog{libc}, in which the outlined data is reused a
lot.
\begin{table}[h]
\centering
\begin{tabular}{r r r r r r}
\toprule
\thead{Shared object} & \thead{Original \\ program size}
& \thead{Original \\ \lstc{.eh\_frame}}
& \thead{Generated \\ \ehelf{} \lstc{.text}}
& \thead{\% of original \\ program size}
& \thead{Growth \\ factor} \\
\midrule
libc-2.27.so
& 1.4 MiB & 130.1 KiB & 313.2 KiB & 21.88 & 2.41 \\
libpthread-2.27.so
& 58.1 KiB & 11.6 KiB & 25.4 KiB & 43.71 & 2.19 \\
ld-2.27.so
& 129.6 KiB & 9.6 KiB & 28.6 KiB & 22.09 & 2.97 \\
hackbench
& 2.9 KiB & 568.0 B & 2.8 KiB & 93.87 & 4.99 \\
Total
& 1.6 MiB & 151.8 KiB & 370.0 KiB & 22.81 & 2.44 \\
\bottomrule
\end{tabular}
\caption{\ehelfs{} space usage}\label{table:bench_space}
\end{table}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Instructions coverage}
@ -937,6 +1016,7 @@ seconds (using only a single core).
\printbibliography{}
%% License notice %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\vfill
\hfill \begin{minipage}{0.7\textwidth}
\begin{flushright}
\itshape{} \small{}

View file

@ -76,3 +76,14 @@
bibsource = {dblp computer science bibliography, https://dblp.org}
}
@article{kell2016libcrunch,
title={Dynamically diagnosing type errors in unsafe code},
author={Kell, Stephen},
journal={ACM SIGPLAN Notices},
volume={51},
number={10},
pages={800--819},
year={2016},
publisher={ACM}
}