36 Commits

Author SHA1 Message Date
Thomas Haller
b93108f07e gobject/performance: decrease warmup time and cleanups
Some tweakings of the time spend during warm up. That mostly matters if
you set very short "--seconds", which can make sense for quickly
checking something. Then the warmup should not take more thatn a certain
percentage of the requested runs.

When we have a constant factor, we still want not to run for more than
10% of the overall test time ... except, we still want to run at least
ESTIMATE_ROUND_TIME_N_RUNS (because we skip the estimation step below).

Also, adjust WARM_UP_ALWAYS_SEC to be only 20% of the test time, for
short test runs.

Also, don't print the messages about "Estimating round time" with a
fixed "--factor".
2025-02-27 07:38:17 +01:00
Thomas Haller
fa66978cd5 gobject/performance: support sub-seconds test lengths on the command line
One test round aims to run for 8msec (TARGET_ROUND_TIME).

As the "--seconds" parameter previously took whole integer numbers, that
meant that we would run at least 125 rounds.

For a quick run, we should also support even faster runs, e.g. to select
only 0.5 seconds.
2025-02-27 07:35:21 +01:00
Thomas Haller
a88a58a23a gobject/performance: only print test message in verbose mode
Historically, there was a verbose mode and a non-verbose mode.
In non-verbose mode (the default), we would still print two lines:

  Running test property-set
  Property set per second: 39329344

Later, this was changed to include the test name in the second line, so
we would print:

  Running test property-set
  property-set: Property set per second: 39329344

But this first line is really just noise, making parsing and reading the
results harder. Hence a "--quiet" mode was added, that only printed one
line per test while keeping the previous default behavior. And all was
good.

Except, unless you want verbose mode, this "Running test" line is still
not very useful and mainly clutters the output.

Supporess it now also in normal mode. It is now only printed in verbose
mode.

This also makes the "--quiet" option do nothing. The option is still
there, maybe we find a future use and we should not break the command
line API by dropping an argument.
2025-02-27 07:33:57 +01:00
Thomas Haller
f0d8eaf83a gobject/performance: add "property-set-signaled" test
g_object_set() optimizes the case where there are no signals connected.
Add a test that sets the property with signals. Obviously, this one is
much slower, since we will freeze and thaw the notifications.
2025-02-27 07:32:46 +01:00
Thomas Haller
6610be0ef9 gobject/performance: also print stddev of runs
It seems useful to me to get an idea of the variance of the timing
measurements. Calculate and print the sample standard deviation of the
timings.
2025-02-27 07:32:46 +01:00
Thomas Haller
1527e1a448 gobject/performance: drop wrong additional warm up during test run
For the test, we actually care to find the fastest test run (and take
"min_elapsed"). That is useful, because that is the run where we
possibly have the least interference from external factors, it was the
run where the CPU solved the problem as fast as it could.

As such, we should not reject the first 5% as additional warm up. If the
first 5% are slower (and part of "warmup"), then they are anyway not
considered. If there is a the fastest run in the first 5 percent, then
we want to take that.

Also note, that the calculation of "avg_elapsed" was wrong, since it
divided by the full "num_rounds" while only summing 95% of the runs.
This is fixed too by now considering all runs.

Fixes: 282d536fd229 ('tests/performance: ensure to always warm up for 2 seconds')
2025-02-27 07:31:06 +01:00
Thomas Haller
201628f87f gobject/performance: improve "performance-run.sh" script
- fix and improve usage output for "performance-run.sh" script.

- add a sleep after compilation. It seems to me, that the first run
  usually performs better, which might be because the temperature of the
  CPU raises and the CPU gets throttled. Unclear whether that is really
  the case, but add a sleep so that all runs start under similar
  conditions where the CPU was idle for a moment.
2025-02-26 12:22:24 +01:00
Thomas Haller
1c9d54d4ea gobject/performance: normalize base factors for test runs
When running the test (without parameters), it estimates a factor for
the run size for each test. That is useful for running a reasonable size
of the test, on different machines.

However, when comparing two runs, it seems important that both runs
share a common factor. Otherwise, the factor is determined differently,
and the test is less comparable. For that there is the "--factor" option
or the GLIB_PERFORMANCE_FACTOR environment variable.

However, the factor option can only set the factors for all tests at the
same time. Optimally, one factor is roughly suitable for all tests, but
it is not, as currently the detected factors on my machine are widely
different

  $ ./build/gobject/tests/performance/performance -v > p
  $ cat p | sed -n -e 's/^Running test //p' -e 's/.*correction factor //p' | sed 'N;s/\n/ /'
  simple-construction 34.78
  simple-construction1 145.45
  complex-construction 11.08
  complex-construction1 20.46
  complex-construction2 23.74
  finalization 4.74
  type-check 37.74
  emit-unhandled 5.63
  emit-unhandled-empty 49.69
  emit-unhandled-generic 7.17
  emit-unhandled-generic-empty 50.63
  emit-unhandled-args 5.20
  emit-handled 3.86
  emit-handled-empty 4.01
  emit-handled-generic 3.96
  emit-handled-generic-empty 7.04
  emit-handled-args 3.78
  notify-unhandled 52.63
  notify-by-pspec-unhandled 156.86
  notify-handled 2.55
  notify-by-pspec-handled 2.66
  property-set 34.63
  property-get 32.92
  refcount 0.83
  refcount-1 2.30
  refcount-toggle 1.33

Adjust the base factors with these measurements.

  PERFORMANCE_FILE="./gobject/tests/performance/performance.c"
  IFS=$'\n'
  for LINE in $(cat p | sed -n -e 's/^Running test //p' -e 's/.*correction factor //p' | sed 'N;s/\n/ /') ; do
    (
      IFS=' '
      set -- $LINE
      TESTNAME="$1"
      FACTOR="$2"

      LINENUMBER="$(grep -n "^    \"$TESTNAME\",$" "$PERFORMANCE_FILE" | cut -d: -f1)"
      LINENUMBER=$((LINENUMBER + 2))

      OLD_FACTOR="$(sed -n "$LINENUMBER s/^    \([0-9]\+\),$/\1/p" "$PERFORMANCE_FILE")"

      NEW_FACTOR="$(awk -v factor="$FACTOR" -v old_factor="$OLD_FACTOR" 'BEGIN {print int(factor * old_factor + 0.5)}')"

      sed -i "$LINENUMBER s/^    \([0-9]\+\),$/    $NEW_FACTOR,/" "$PERFORMANCE_FILE"
    )
  done

Afterwards, we get comparable factors:

  $ ./build/gobject/tests/performance/performance -v > p2
  $ cat p2 | sed -n -e 's/^Running test //p' -e 's/.*correction factor //p' | sed 'N;s/\n/ /'
  simple-construction 0.98
  simple-construction1 0.75
  complex-construction 0.99
  complex-construction1 0.96
  complex-construction2 1.02
  finalization 1.05
  type-check 0.98
  emit-unhandled 1.01
  emit-unhandled-empty 1.10
  emit-unhandled-generic 1.03
  emit-unhandled-generic-empty 1.07
  ...

Of course, this measurement was taken in my setup.  But I think it
brings the base factors into a comparable range for most users.

Also, the commit message shows an ugly script how you can re-generate
this for your own purposes.
2025-02-26 12:22:24 +01:00
Thomas Haller
0e1597ffb9 gobject/performance: rework setting the base factor for number of rounds
Move the factor inside the PerformanceTest structure, so it can be
programatically accessed.

More importantly, the number is now expressed directly beside the test
setup (the PerformanceTest structure), all at one place.

Also, each test now gets a separate factor.

This change will be useful in the next commit. So far there is no
notable change in behavior.
2025-02-26 12:22:24 +01:00
Thomas Haller
6a231008e4 gobject/performance: fix "type-check" test to not optimize out test code
Despite assigning the function to a variable, gcc can still detect that
the function never changes and most of the test code is optimized out.
Initialize it somewhere, where the compiler cannot prove that this
function pointer is always set to the same value.

We could also make the pointer volatile, but this approach seems
preferable to me.
2025-02-26 12:22:24 +01:00
Philip Withnall
e35cfef509
performance: Add explicit casts for some double → other numeric type conversions
If we enable `-Wfloat-conversion`, these warn about a possible loss of
precision due to an implicit conversion from `double` to some other
numeric type.

The warning is correct: there is a possible loss of precision here. In
these instances, we don’t care, as the floating point arithmetic is
being done to do some imprecise scaling or imprecise timing. A loss of
precision is not a problem.

So, add an explicit cast to squash the warning.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3405
2024-06-28 14:43:26 +01:00
Philip Withnall
b7153f5072
performance: Fix signedness of ints throughout
The tests were using a lot of signed `int`s when actually the values
being handled were always non-negative. Use `unsigned int` consistently
throughout.

Take the opportunity to move declarations of loop iterator variables
into the loops.

This introduces no functional changes.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3405
2024-06-28 14:41:48 +01:00
Thomas Haller
4d5047e0e7 tests/performance: add performance-run.sh script for running performance test
The main use of the performance test is to run it for two (or more) commits
and compare the results. Doing that manually, is cumbersome.

Add a (very hacky) script to help with that. For usage, see the comment
on top of the script.

Example:

  # first:
  meson build -Dprefix=/tmp/glib/ -Db_lto=true --buildtype release -Ddebug=true

  # then:
  GLIB_PERFORMANCE_FACTOR=17.06 \
  PERF='perf stat -r 4 -B' \
  PATCH="2.80.0..th/performance" \
  COMMITS="2.79.3 2.80.0" \
  /tmp/performance-run.sh -s 1 property-get property-set

This will build the requested $COMMITS and print something like:

  ...
  >>> combined result > /tmp/glib-performance-output.all
  Running test property-get
  property-get: Property get per second: 35742719 37208288 (+4.1%)
  Running test property-set
  property-set: Property set per second: 32341232 36942399 (+14.2%)
  Running test property-get
  property-get: Property get per second: 36934401 37143479 (+0.566%)
  Running test property-set
  property-set: Property set per second: 38046387 38165548 (+0.313%)
  Running test property-get
  property-get: Property get per second: 34759576 36359761 (+4.6%)
  Running test property-set
  property-set: Property set per second: 35262505 37651733 (+6.78%)
  Running test property-get
  property-get: Property get per second: 37014537 32870906 (-11.2%)
  Running test property-set
  property-set: Property set per second: 36633026 38216846 (+4.32%)

   Performance counter stats for './build/gobject/tests/performance/performance -s 1 property-get property-set' (4 runs):

            1,312.18 msec task-clock:u                     #    1.000 CPUs utilized               ( +-  4.82% )
                   0      context-switches:u               #    0.000 /sec
                   0      cpu-migrations:u                 #    0.000 /sec
                 121      page-faults:u                    #   92.213 /sec                        ( +-  0.24% )
       5,221,701,009      cycles:u                         #    3.979 GHz                         ( +-  2.61% )
      19,035,814,175      instructions:u                   #    3.65  insn per cycle              ( +-  0.00% )
       4,335,306,010      branches:u                       #    3.304 G/sec                       ( +-  0.00% )
              13,031      branch-misses:u                  #    0.00% of all branches             ( +-  4.17% )
                          TopdownL1                 #     10.3 %  tma_backend_bound
                                                    #      5.3 %  tma_bad_speculation
                                                    #     11.4 %  tma_frontend_bound
                                                    #     73.1 %  tma_retiring             ( +-  2.15% )

  [1]             1.3127 +- 0.0634 seconds time elapsed  ( +-  4.83% )
  [2]             1.2631 +- 0.0253 seconds time elapsed  ( +-  2.00% )

  property-get: Property get per second: 35742719 , 36934401 , 34759576 , 37014537  ;  37208288 , 37143479 , 36359761 , 32870906  ;
  property-set: Property set per second: 32341232 , 38046387 , 35262505 , 36633026  ;  36942399 , 38165548 , 37651733 , 38216846  ;
2024-03-18 13:56:03 +00:00
Thomas Haller
7b9e6d4949 tests/performance: add "refcount-toggle" test
Performance test for emitting toggle reference notifications.
2024-03-18 13:56:03 +00:00
Thomas Haller
2b1a7e30b1 tests/performance: avoid check for toggle notification in "property-{get,set}"
Bumping the reference count from 1 to 2 (and back) is more expensive,
due to the check for toggle notifications.

We have a performance test already that hits that code path. Avoid that
for he "property-{get,set}" tests, so we avoid the known overhead and
test more relevant parts.
2024-03-18 13:56:02 +00:00
Thomas Haller
b6789dd1ea tests/performance: add "refcount-1" test
When an object has ref-count 1, then calling g_object_ref() requires a
check for toggle references. That is slower. Add a test for that case.
2024-03-18 13:56:02 +00:00
Thomas Haller
282d536fd2 tests/performance: ensure to always warm up for 2 seconds
Despite all the efforts, there still seems to be a lot of noise in the
performance measurement. Especially, the first iterations seem to run
faster. Maybe that is because the kernel didn't yet determine that the
process is CPU bound and is less likely to schedule it out Or maybe it's
because burning the cycles heats up the CPU and it gets throttled after
a while. It's unclear why, and it's even unclear whether this really
happens. But from my observations, it seems to do.

Hence, more warm up.

- the first time we enter the test, ensure that we keep the CPU busy for
  at 2 seconds. This additional warm up (WARM_UP_ALWAYS_SEC) is
  global, and not per test.

- for each test, ignore the first 5% of the runs. It seems those tend to
  run faster, thus skewing the results.

- if the user specifies a "--factor", the warm up operations are the
  same and independent from external factors (such as time
  measurements).

Note that this matters the most, when you want to run the executable
twice in a row and compare the results.
2024-03-18 13:56:02 +00:00
Thomas Haller
29a69d5a1b tests/performance: add "factor" argument to performance test
By default, the test estimates a run factor for each test. This means,
if you run performance under `perf`, the results are not comparable,
as the run time depends on the estimated factor.

Add an option, to set a fixed factor.

Of course, there is only one factor argument for all tests.  Quite
possibly, you would want to run each test individually with a factor
appropriate for the test. On the other hand, all tests should be tuned
so that the same factor gives a similar test duration. So this may not
be a concern, or the tests should be adjusted. In any case, the option
is most useful when running only one test explicitly.

You can get a suitable factor by running the test once with "--verbose".

Another use case is if you run the benchmark under valgrind. Valgrind
slows down the run so much, that the estimated factor would be quite
off. As a result, the chosen code paths are different from the real run.
By setting the factor, the timing measurements don't affect the executed
code.
2024-03-18 13:56:02 +00:00
Thomas Haller
e5e3c37d22 tests/performance: add "--quiet" argument to performance
The default output is annoyingly verbose. You see

  Running test simple-construction
  simple-construction: Millions of constructed objects per second: 33.498
  Running test simple-construction1
  simple-construction1: Millions of constructed objects per second: 142.493
  Running test complex-construction
  complex-construction: Millions of constructed objects per second: 14.304
  Running test complex-construction1
  ...

where the "Running test" lines just clutter the output. In fact so much
so, that my terminal fills up and I don't see the output of all tests in
one page. The "Running test" line is not so useful, because I mostly
care about the test result, and that line already contains the test
name.

Add an option to silence this.
2024-03-18 13:56:02 +00:00
Thomas Haller
65a59bde57 tests/performance: print result in unique line
Previously, the result lines are not unique, for example

  Running test simple-construction
  Millions of constructed objects per second: 27.629
  Running test simple-construction1
  Millions of constructed objects per second: 151.879
  ...

That is undesirable, because we might want to parse the test results
with a script, and that's easier when the line is unique.

Change to:

  Running test simple-construction
  simple-construction: Millions of constructed objects per second: 27.629
  Running test simple-construction1
  simple-construction1: Millions of constructed objects per second: 151.879
  ...
2024-03-18 13:56:02 +00:00
Damien Zammit
f25a9ca10c Initial test of Hurd CI - (run_tests.sh status ignored) 2023-10-18 23:33:04 +00:00
Philip Withnall
0e84e28978 tests: Don’t run the GObject performance tests under valgrind
They take too long and time out, and are not particularly useful to run
under valgrind because they aren’t designed to test code coverage.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2023-02-16 12:52:30 +00:00
Marco Trevisan (Treviño)
c6f252108c gobject/tests/performance: Add object get/set performance tests 2022-12-14 03:05:50 +01:00
Marco Trevisan (Treviño)
77a2d26ea2 gobject/tests/performance: Add object notify performance tests 2022-12-14 03:05:50 +01:00
Marco Trevisan (Treviño)
3c56d661d8 meson: Use test setup environment instead of repeating it everywhere 2022-10-31 14:08:31 +01:00
Marco Trevisan (Treviño)
62dca6c1cf meson, ci: Support tests that can fail under certain conditions
We have tests that are failing in some environments, but it's
difficult to handle them because:
 - for some environments we just allow all the tests to fail: DANGEROUS
 - when we don't allow failures we have flacky tests: A CI pain

So, to avoid this and ensure that:
 - New failing tests are tracked in all platforms
 - gitlab integration on tests reports is working
 - coverage is reported also for failing tests

Add support for `can_fail` keyword on tests that would mark the test as
part of the `failing` test suite.
Not adding the suite directly when defining the tests as this is
definitely simpler and allows to define conditions more clearly (see next
commits).

Now, add a default test setup that does not run the failing and flaky tests
by default (not to bother distributors with testing well-known issues) and
eventually run all the tests in CI:
 - Non-flaky tests cannot fail in all platforms
 - Failing and Flaky tests can fail

In both cases we save the test reports so that gitlab integration is
preserved.
2022-10-31 14:08:29 +01:00
Philip Withnall
4bc284fca6 Merge branch 'wip/smcv/deprecated-prop-followup' into 'main'
Run tests with G_ENABLE_DIAGNOSTIC=1

See merge request GNOME/glib!2889
2022-10-15 21:31:29 +00:00
Simon McVittie
88e160dfe4 tests: Move common test environment variables to top level
Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-09-21 11:19:28 +01:00
Xavier Claessens
c00df192ee meson: Set install_tag on installed tests files
This could be done automatically by Meson, this commit can be reverted
when we have that Meson PR in our CI:
https://github.com/mesonbuild/meson/pull/10829
2022-09-20 11:30:02 -04:00
Simon McVittie
72868c026d gobject/tests/performance: Only run a quick version as installed-tests
ginsttest-runner defaults to timing out each test after 5 minutes,
but gobject/tests/performance/performance.c defaults to running each
of 18 tests for 15 seconds. The result is close enough to 5 minutes
that the setup overhead is enough to make it time out.

We're only running these tests to prove that they still work, not to
get meaningful performance numbers, so cut them down to 1 second per
test-case (the result of which is that performance.c takes about a
minute).

Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-07-24 17:34:55 +01:00
Simon McVittie
0714bcb7f4 gobject/tests/performance: Use the other installed-tests template
These are not GTest tests, and don't output TAP.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-07-24 17:15:47 +01:00
Marc-André Lureau
a5d551e2be gobject/tests/performance: fix leaks
Easily spotted by ASAN.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2022-06-23 17:18:21 +04:00
Philip Withnall
6f435e40cd tests: Run GObject performance tests under meson test
Pass arguments to them so that they take minimal time. This will not
produce useful performance profiling results, but will smoketest that
the tests still run, don’t crash, and therefore probably aren’t
bitrotting too badly.

This is useful because a fair amount of work has gone into these
performance tests, and they’re useful every few years to analyse and
compare GObject performance. We don’t want them to bitrot between uses.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2022-06-21 12:57:33 +01:00
Philip Withnall
6747702d77 tests: Fix use of deprecated threading API in performance-threaded
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2022-06-21 12:50:31 +01:00
Philip Withnall
6b8240f061 tests: Fix performance-threaded test when run for zero seconds
When running the test with `-s 0` it would previously crash. Fix that,
and make it so that it only does a single test run in that case.

This will be useful in an upcoming commit for smoketesting the test to
avoid bitrot.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2022-06-21 12:50:31 +01:00
Philip Withnall
d463de05b1 tests: Move GObject performance tests to gobject/tests/performance/
This doesn’t change the tests’ behaviour, but moves them to a slightly
more logical location.

They are still not installed or run by default.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #1434
2022-06-08 11:30:31 +01:00