libqb/include
Jan Pokorný 32555d8af9
tests: add a script to generate callsite-heavy logging client...
...so as to evaluate use of resources.  In particular, the intention
here is to uncover the observable differences between the same logging
code built with callsite section (default when available) and
purposefully (overriding that default by force) without it.
To allow for the latter being applied conveniently, new macro,
QB_KILL_ATTRIBUTE_SECTION, can be defined in the compile-time of the
client code that wishes to opt-out from the callsite section feature.

* * *

Following is a discussion on these differences, sticking with the
logging client code generated with the script defaults, i.e., as it
would be run with these switches:
  --callsite-count=3640
  --branching-factor=3
  --callsites-per-fnc=10
  --round-count=1000
and then built twice (as detailed in
tests/functional/log_external/Makefile.am):
  * log_callsite_bench_sectionfull
    - with callsite section
  * log_callsite_bench_sectionless
    - without callsite section, imposed with -DQB_KILL_ATTRIBUTE_SECTION
      in CPPFLAGS

--> Static size of the executable:

$ size -B log_callsite_bench_section* | tr '\t' ' ' | tr -s ' ' \
  | cut --complement -d' ' -f6 | column -t
> text    data    bss  dec     filename
> 82761   146180  4    228945  log_callsite_bench_sectionfull
> 190000  588     4    190592  log_callsite_bench_sectionless

We can see that sectionfull is few kB bigger in the object sections
of interest, though the text-data ratio changes considerably, with
code section being cut in half in comparison to sectionless, which
can actually help the code locality (and hence utilization
of CPU caches) in the former case.

--> Dynamic memory/heap operations:

$ valgrind --log-fd=1 ./log_callsite_bench_section{full,less} 2>/dev/null

total heap usage:
- log_callsite_bench_sectionfull:
> 88 allocs, 87 frees, 3,427 bytes allocated[*]
- log_callsite_bench_sectionless:
> 11,894 allocs, 11,893 frees, 486,035 bytes allocated[*]

[*] "32 bytes in 1 blocks still reachable" looks rather as a spurious
    warning on the valgrind's side (matter of dynamic linking library)

Apparently, sectionless keeps stirring the heap constantly, with all
the possible downsides associated with that, like hitting the page
faults leading to less timely execution.

--> Run-time efficiency:

$ time ./log_callsite_bench_section{full,less} 2>/dev/null

mean attempts out of 3 consecutive runs:
- log_callsite_bench_sectionfull:
> real	0m1.298s
> user	0m0.965s
> sys	0m0.331s

- log_callsite_bench_sectionless:
> real	0m1.436s
> user	0m1.067s
> sys	0m0.365s

As expected, we can observe sectionfull is slightly faster/more
efficient.

* * *

Based on the above, we can conclude that leveraging the callsite
section for logging as facilitated by the toolchain intrinsics is
beneficial, especially for performance-critical applications (corosync
being the showcase here).  Therefore it's desired to struggle for
retaining this nifty trick despite some troubles emerged with recent
binutils releases (starting with 2.29) and the changed behaviour we
relied on so far in respective ld.bfd linkers (as mentioned in
preceding commits).  That motive is immediately followed -- well,
judging the impact fairly, actually outclassed -- with the intention
to preserve binary compatibility (incl. continuous library support for
callsite section offloading spread in the existing client space widely
for quite some years already) to the utmost extent possible.

Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
2017-12-12 20:48:23 +01:00
..
qb tests: add a script to generate callsite-heavy logging client... 2017-12-12 20:48:23 +01:00
.gitignore Cleanup the .gitignore files 2012-05-09 21:43:58 +10:00
Makefile.am build: include: fix extra trailing newline 2016-03-10 22:44:49 +01:00
os_base.h Properly discover SO_NOSIGPIPE and MSG_SIGNAL 2013-03-12 21:13:47 +11:00
tlist.h Unify to QB_TRUE/QB_FALSE a boolean value 2013-01-11 02:01:06 +09:00