I was also wondering, checked the actual execution for both paths (with & without [[likely]]), and if the benchmarks are accurate, AppleClang 15 doesn't seem to make any change in this case (yet?).
<details><summary>FeeFracEvaluate bench</summary>
cmake --build build && ./build/src/bench/bench_bitcoin -filter='FeeFracEvaluate.*' --min-time=10000
// tried a few different ways of testing it, none of them showed any difference
#include <bench/bench.h>
#include <util/feefrac.h>
#include <random.h>
#include <vector>
static void FeeFracEvaluate_likely(benchmark::Bench& bench)
{
FastRandomContext rng(true);
constexpr size_t NUM_SAMPLES = 1'000'000;
std::vector<int64_t> fees(NUM_SAMPLES);
std::vector<int32_t> sizes(NUM_SAMPLES);
std::vector<int32_t> at_sizes(NUM_SAMPLES);
for (size_t i = 0; i < NUM_SAMPLES; ++i) {
fees[i] = rng.randrange(0x200000000);
sizes[i] = 1 + rng.randrange(INT32_MAX - 1);
at_sizes[i] = rng.randrange(INT32_MAX);
}
bench.run([&] {
for (size_t i = 0; i < NUM_SAMPLES; ++i) {
FeeFrac ff{fees[i], sizes[i]};
auto fee = i % 2 ? ff.EvaluateDown(at_sizes[i]) : ff.EvaluateUp(at_sizes[i]);
ankerl::nanobench::doNotOptimizeAway(fee);
}
});
}
static void FeeFracEvaluate_unlikely(benchmark::Bench& bench)
{
FastRandomContext rng(true);
constexpr size_t NUM_SAMPLES = 1'000'000;
std::vector<int64_t> fees(NUM_SAMPLES);
std::vector<int32_t> sizes(NUM_SAMPLES);
std::vector<int32_t> at_sizes(NUM_SAMPLES);
for (size_t i = 0; i < NUM_SAMPLES; ++i) {
fees[i] = 0x200000000 + rng.randrange(0x200000000);
sizes[i] = 1 + rng.randrange(INT32_MAX - 1);
at_sizes[i] = rng.randrange(INT32_MAX);
}
bench.run([&] {
for (size_t i = 0; i < NUM_SAMPLES; ++i) {
FeeFrac ff{fees[i], sizes[i]};
auto fee = i % 2 ? ff.EvaluateDown(at_sizes[i]) : ff.EvaluateUp(at_sizes[i]);
ankerl::nanobench::doNotOptimizeAway(fee);
}
});
}
BENCHMARK(FeeFracEvaluate_likely, benchmark::PriorityLevel::HIGH);
BENCHMARK(FeeFracEvaluate_unlikely, benchmark::PriorityLevel::HIGH);
</details>
with [[likely]] (2x):
| ns/op | op/s | err% | total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
| 1,133,642.20 | 882.11 | 0.1% | 11.01 | FeeFracEvaluate_likely
| 6,809,775.64 | 146.85 | 0.1% | 10.62 | FeeFracEvaluate_unlikely
| ns/op | op/s | err% | total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
| 1,132,721.68 | 882.83 | 0.0% | 11.00 | FeeFracEvaluate_likely
| 6,811,900.44 | 146.80 | 0.1% | 10.62 | FeeFracEvaluate_unlikely
without any attributes (2x):
| ns/op | op/s | err% | total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
| 1,133,687.15 | 882.08 | 0.1% | 11.00 | FeeFracEvaluate_likely
| 6,807,422.74 | 146.90 | 0.0% | 10.62 | FeeFracEvaluate_unlikely
| ns/op | op/s | err% | total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
| 1,133,233.44 | 882.43 | 0.1% | 11.04 | FeeFracEvaluate_likely
| 6,809,800.59 | 146.85 | 0.1% | 10.63 | FeeFracEvaluate_unlikely