Build the benchmarks as part of the CI (#5965)

* Build the benchmarks as part of 'linux-meson-gcc-tests' step
* Fix bench_il build error
* Add macro to avoid compiler optimization on benchmarked code
* Fix incorrect format specifier
* Cast to uint64_t
This commit is contained in:
Anton Angelov 2026-03-08 07:15:18 +02:00 committed by GitHub
parent 5bc6c7e30e
commit 98670969eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 47 additions and 15 deletions

View file

@ -82,7 +82,7 @@ jobs:
build_system: meson
compiler: gcc
run_tests: true
meson_options: -Dbuildtype=release --werror
meson_options: -Dbuildtype=release -Denable_benchmarks=true --werror
enabled: ${{ needs.changes.outputs.edited == 'true' }}
timeout: 45
cflags: -DRZ_ASSERT_STDOUT=1

View file

@ -152,23 +152,23 @@ static void bench_rz_ht_pu_combined(RzTable *t_out) {
});
RZ_BENCH_RUN_I("[HtPU] lookup (100 elements)", i, t_out, ITERATION_COUNT, {
PUKey temp_key = make_pu_key(reshuffle_key(i, 100, UT64_MAX));
ut64 result = ht_pu_find(ht_100, &temp_key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_pu_find(ht_100, &temp_key, NULL));
});
RZ_BENCH_RUN_I("[HtPU] lookup (1k elements)", i, t_out, ITERATION_COUNT, {
PUKey temp_key = make_pu_key(reshuffle_key(i, 1000, UT64_MAX));
ut64 result = ht_pu_find(ht_1k, &temp_key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_pu_find(ht_1k, &temp_key, NULL));
});
RZ_BENCH_RUN_I("[HtPU] lookup (10k elements)", i, t_out, ITERATION_COUNT, {
PUKey temp_key = make_pu_key(reshuffle_key(i, 10000, UT64_MAX));
ut64 result = ht_pu_find(ht_10k, &temp_key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_pu_find(ht_10k, &temp_key, NULL));
});
RZ_BENCH_RUN_I("[HtPU] lookup (100k elements)", i, t_out, ITERATION_COUNT, {
PUKey temp_key = make_pu_key(reshuffle_key(i, 100000, UT64_MAX));
ut64 result = ht_pu_find(ht_100k, &temp_key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_pu_find(ht_100k, &temp_key, NULL));
});
RZ_BENCH_RUN_I("[HtPU] lookup (1M elements)", i, t_out, ITERATION_COUNT, {
PUKey temp_key = make_pu_key(reshuffle_key(i, 1000000, UT64_MAX));
ut64 result = ht_pu_find(ht_1m, &temp_key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_pu_find(ht_1m, &temp_key, NULL));
});
ht_pu_free(ht_100);
@ -181,9 +181,12 @@ static void bench_rz_ht_pu_combined(RzTable *t_out) {
free(keys);
}
static char *generate_su_key(ut64 index) {
static char *generate_su_key(ut64 i) {
char buffer[UT8_MAX];
// cast to uint64_t to avoid format specifier (PRIx64) mismatch
uint64_t index = (uint64_t)i;
// Try to mimic real world string keys
switch (index % 8) {
case 0:
@ -296,23 +299,23 @@ static void bench_rz_ht_su_combined(RzTable *t_out) {
});
RZ_BENCH_RUN_I("[HtSU] lookup (100 elements)", i, t_out, ITERATION_COUNT, {
const char *key = precomputed_keys[reshuffle_key(i, 100, ITERATION_COUNT)];
ut64 result = ht_su_find(ht_100, key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_su_find(ht_100, key, NULL));
});
RZ_BENCH_RUN_I("[HtSU] lookup (1k elements)", i, t_out, ITERATION_COUNT, {
const char *key = precomputed_keys[reshuffle_key(i, 1000, ITERATION_COUNT)];
ut64 result = ht_su_find(ht_1k, key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_su_find(ht_1k, key, NULL));
});
RZ_BENCH_RUN_I("[HtSU] lookup (10k elements)", i, t_out, ITERATION_COUNT, {
const char *key = precomputed_keys[reshuffle_key(i, 10000, ITERATION_COUNT)];
ut64 result = ht_su_find(ht_10k, key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_su_find(ht_10k, key, NULL));
});
RZ_BENCH_RUN_I("[HtSU] lookup (100k elements)", i, t_out, ITERATION_COUNT, {
const char *key = precomputed_keys[reshuffle_key(i, 100000, ITERATION_COUNT)];
ut64 result = ht_su_find(ht_100k, key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_su_find(ht_100k, key, NULL));
});
RZ_BENCH_RUN_I("[HtSU] lookup (1M elements)", i, t_out, ITERATION_COUNT, {
const char *key = precomputed_keys[reshuffle_key(i, 1000000, ITERATION_COUNT)];
ut64 result = ht_su_find(ht_1m, key, NULL);
RZ_DONT_OPTIMIZE(ut64, ht_su_find(ht_1m, key, NULL));
});
ht_su_free(ht_100);

View file

@ -12,7 +12,7 @@
static void bench_rz_il_mem_loadw(const char *title, RzTable *t_out, ut32 bit_size, bool big_endian) {
RzBuffer *buf = rz_buf_new_empty(bit_size);
RzILMem *mem = rz_il_mem_new(buf, 64);
RzILMem *mem = rz_il_mem_new_borrowed(buf, 64);
RzBitVector *key = rz_bv_new_from_ut64(64, 0x12345678abcdef);
RZ_BENCH_RUN(title, t_out, 1000000, {

View file

@ -13,7 +13,7 @@ static void bench_rz_bits_trailing_zeros(RzTable *t_out) {
ut64 v = 0;
RZ_BENCH_RUN("bench_rz_bits_trailing_zeros", t_out, 5000000, {
volatile ut64 result = rz_bits_trailing_zeros(v++);
RZ_DONT_OPTIMIZE(size_t, rz_bits_trailing_zeros(v++));
});
}

View file

@ -73,4 +73,33 @@ RZ_API void rz_bench_report(RZ_NONNULL RzBenchCtx *ctx, RZ_NONNULL RzTable *t);
free(table_out); \
rz_table_free(T);
#if defined(__GNUC__) || defined(__clang__)
/**
* \def Helper macro to prevent compiler optimizations on benchmarked code.
* \param type Return type of the expression \p x.
* \param x Function or code to be executed.
*/
#define RZ_DONT_OPTIMIZE(type, x) \
do { \
type tmp_ = (x); \
__asm__ volatile("" : : "r,m"(tmp_) : "memory"); \
} while (0)
#elif defined(_MSC_VER)
#include <intrin.h>
#define RZ_DONT_OPTIMIZE(type, x) \
do { \
type tmp_ = (x); \
_WriteBarrier(); \
*(volatile char *)&tmp_; \
_ReadBarrier(); \
} while (0)
#else
// Fallback
#define RZ_DONT_OPTIMIZE(type, x) \
do { \
volatile type tmp_ = (x); \
(void)tmp_; \
} while (0)
#endif
#endif // BENCH_UTILS_H

View file

@ -21,7 +21,7 @@ if get_option('enable_benchmarks')
benchmarks = [
'bitvector',
'il',
'ht'
'ht',
'util'
]