From: Namhyung Kim <namhyung@kernel.org>
To: Michal Pluta <michalpl2003@gmail.com>
Cc: acme@kernel.org, "Thomas Gleixner" <tglx@kernel.org>,
"Ingo Molnar" <mingo@redhat.com>,
"Peter Zijlstra" <peterz@infradead.org>,
"Darren Hart" <dvhart@infradead.org>,
"Davidlohr Bueso" <dave@stgolabs.net>,
"André Almeida" <andrealmeid@igalia.com>,
"Mark Rutland" <mark.rutland@arm.com>,
"Alexander Shishkin" <alexander.shishkin@linux.intel.com>,
"Jiri Olsa" <jolsa@kernel.org>, "Ian Rogers" <irogers@google.com>,
"Adrian Hunter" <adrian.hunter@intel.com>,
"James Clark" <james.clark@linaro.org>,
"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: Re: [PATCH 3/8] perf bench futex: Use the whole timeval for elapsed times
Date: Mon, 5 Oct 2026 16:54:26 -0700 [thread overview]
Message-ID: <asQ4sju-WXehW8oP@google.com> (raw)
In-Reply-To: <20260926190407.1106421-4-michalpl2003@gmail.com>
On Sat, Sep 26, 2026 at 08:04:02PM +0100, Michal Pluta wrote:
> Several futex benchmarks read only one field of the struct timeval that
> timersub() produces, so part of the elapsed time is lost.
>
> 'futex wake', 'futex wake-parallel' and 'futex requeue' print tv_usec,
> so a run that takes 1.5 s is shown as 500 ms. 'futex hash' and 'futex
> lock-pi' divide their operation count by tv_sec, which overstates the
> throughput when a run is stopped early, and gives 0 if that happens
> within the first second. Their "total secs" is truncated in the same
> way.
>
> Use the whole timeval and print "total secs" with two decimals. With
> --runtime=0 the rate is now computed over the time that actually
> elapsed, instead of showing 0.
Can you please add an example output of one of the benchmarks in the
commit message?
Thanks,
Namhyung
>
> Fixes: 27db78307481 ("perf bench: Add futex-wake microbenchmark")
> Fixes: 0fb298cf95c0 ("perf bench: Add futex-requeue microbenchmark")
> Fixes: a043971141f1 ("perf bench: Add futex-hash microbenchmark")
> Fixes: d2f3f5d2e9ca ("perf bench futex: Add lock_pi stresser")
> Fixes: d65817b4e707 ("perf bench futex: Support parallel waker threads")
> Assisted-by: LLM
> Signed-off-by: Michal Pluta <michalpl2003@gmail.com>
> ---
> tools/perf/bench/futex-hash.c | 12 ++++++++----
> tools/perf/bench/futex-lock-pi.c | 12 ++++++++----
> tools/perf/bench/futex-requeue.c | 8 +++++---
> tools/perf/bench/futex-wake-parallel.c | 8 ++++++--
> tools/perf/bench/futex-wake.c | 6 ++++--
> 5 files changed, 31 insertions(+), 15 deletions(-)
>
> diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
> index 7e29f04da744..32b88df8ee6d 100644
> --- a/tools/perf/bench/futex-hash.c
> +++ b/tools/perf/bench/futex-hash.c
> @@ -18,6 +18,7 @@
> #include <stdlib.h>
> #include <linux/compiler.h>
> #include <linux/kernel.h>
> +#include <linux/time64.h>
> #include <linux/zalloc.h>
> #include <sys/time.h>
> #include <sys/mman.h>
> @@ -118,18 +119,19 @@ static void print_summary(void)
> unsigned long avg = avg_stats(&throughput_stats);
> double stddev = stddev_stats(&throughput_stats);
>
> - printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
> + printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %.2f\n",
> !params.silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
> - (int)bench__runtime.tv_sec);
> + bench__runtime.tv_sec + bench__runtime.tv_usec / (double)USEC_PER_SEC);
> futex_print_nbuckets(¶ms);
> }
>
> int bench_futex_hash(int argc, const char **argv)
> {
> int ret = 0;
> cpu_set_t *cpuset;
> struct sigaction act;
> unsigned int i;
> + u64 runtime_us;
> pthread_attr_t thread_attr;
> struct worker *worker = NULL;
> struct perf_cpu_map *cpu;
> @@ -229,9 +231,11 @@ int bench_futex_hash(int argc, const char **argv)
> cond_destroy(&thread_worker);
> mutex_destroy(&thread_lock);
>
> + runtime_us = (u64)bench__runtime.tv_sec * USEC_PER_SEC + bench__runtime.tv_usec;
> +
> for (i = 0; i < params.nthreads; i++) {
> - unsigned long t = bench__runtime.tv_sec > 0 ?
> - worker[i].ops / bench__runtime.tv_sec : 0;
> + unsigned long t = runtime_us ?
> + (u64)worker[i].ops * USEC_PER_SEC / runtime_us : 0;
> update_stats(&throughput_stats, t);
> if (!params.silent) {
> if (params.nfutexes == 1)
> diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
> index 40640b674427..7190f5102e09 100644
> --- a/tools/perf/bench/futex-lock-pi.c
> +++ b/tools/perf/bench/futex-lock-pi.c
> @@ -13,6 +13,7 @@
> #include <subcmd/parse-options.h>
> #include <linux/compiler.h>
> #include <linux/kernel.h>
> +#include <linux/time64.h>
> #include <linux/zalloc.h>
> #include <errno.h>
> #include <perf/cpumap.h>
> @@ -66,9 +67,9 @@ static void print_summary(void)
> unsigned long avg = avg_stats(&throughput_stats);
> double stddev = stddev_stats(&throughput_stats);
>
> - printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
> + printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %.2f\n",
> !params.silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
> - (int)bench__runtime.tv_sec);
> + bench__runtime.tv_sec + bench__runtime.tv_usec / (double)USEC_PER_SEC);
> futex_print_nbuckets(¶ms);
> }
>
> @@ -168,6 +169,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
> {
> int ret = 0;
> unsigned int i;
> + u64 runtime_us;
> struct sigaction act;
> struct perf_cpu_map *cpu;
>
> @@ -233,9 +235,11 @@ int bench_futex_lock_pi(int argc, const char **argv)
> cond_destroy(&thread_worker);
> mutex_destroy(&thread_lock);
>
> + runtime_us = (u64)bench__runtime.tv_sec * USEC_PER_SEC + bench__runtime.tv_usec;
> +
> for (i = 0; i < params.nthreads; i++) {
> - unsigned long t = bench__runtime.tv_sec > 0 ?
> - worker[i].ops / bench__runtime.tv_sec : 0;
> + unsigned long t = runtime_us ?
> + (u64)worker[i].ops * USEC_PER_SEC / runtime_us : 0;
>
> update_stats(&throughput_stats, t);
> if (!params.silent)
> diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
> index 0748b0fd689e..5d4708f40c60 100644
> --- a/tools/perf/bench/futex-requeue.c
> +++ b/tools/perf/bench/futex-requeue.c
> @@ -223,6 +223,7 @@ int bench_futex_requeue(int argc, const char **argv)
> for (j = 0; j < bench_repeat && !done; j++) {
> unsigned int nrequeued = 0, wakeups = 0;
> struct timeval start, end, runtime;
> + u64 runtime_us;
>
> /* create, launch & block all threads */
> block_threads(worker, cpu);
> @@ -267,23 +268,24 @@ int bench_futex_requeue(int argc, const char **argv)
>
> gettimeofday(&end, NULL);
> timersub(&end, &start, &runtime);
> + runtime_us = (u64)runtime.tv_sec * USEC_PER_SEC + runtime.tv_usec;
>
> update_stats(&requeued_stats, nrequeued);
> - update_stats(&requeuetime_stats, runtime.tv_usec);
> + update_stats(&requeuetime_stats, runtime_us);
>
> if (!params.silent) {
> if (!params.pi)
> printf("[Run %d]: Requeued %d of %d threads in "
> "%.4f ms\n", j + 1, nrequeued,
> params.nthreads,
> - runtime.tv_usec / (double)USEC_PER_MSEC);
> + runtime_us / (double)USEC_PER_MSEC);
> else {
> nrequeued -= wakeups;
> printf("[Run %d]: Awoke and Requeued (%d+%d) of "
> "%d threads in %.4f ms\n",
> j + 1, wakeups, nrequeued,
> params.nthreads,
> - runtime.tv_usec / (double)USEC_PER_MSEC);
> + runtime_us / (double)USEC_PER_MSEC);
> }
>
> }
> diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
> index a089d8ee4b02..fa70b7d4b473 100644
> --- a/tools/perf/bench/futex-wake-parallel.c
> +++ b/tools/perf/bench/futex-wake-parallel.c
> @@ -192,7 +192,9 @@ static void print_run(struct thread_data *waking_worker, unsigned int run_num)
> init_stats(&__waketime_stats);
>
> for (i = 0; i < params.nwakes; i++) {
> - update_stats(&__waketime_stats, waking_worker[i].runtime.tv_usec);
> + update_stats(&__waketime_stats,
> + (u64)waking_worker[i].runtime.tv_sec * USEC_PER_SEC +
> + waking_worker[i].runtime.tv_usec);
> update_stats(&__wakeup_stats, waking_worker[i].nwoken);
> }
>
> @@ -229,7 +231,9 @@ static void do_run_stats(struct thread_data *waking_worker)
> unsigned int i;
>
> for (i = 0; i < params.nwakes; i++) {
> - update_stats(&waketime_stats, waking_worker[i].runtime.tv_usec);
> + update_stats(&waketime_stats,
> + (u64)waking_worker[i].runtime.tv_sec * USEC_PER_SEC +
> + waking_worker[i].runtime.tv_usec);
> update_stats(&wakeup_stats, waking_worker[i].nwoken);
> }
>
> diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
> index 58427bb55c03..12a75be077a0 100644
> --- a/tools/perf/bench/futex-wake.c
> +++ b/tools/perf/bench/futex-wake.c
> @@ -191,6 +191,7 @@ int bench_futex_wake(int argc, const char **argv)
> for (j = 0; j < bench_repeat && !done; j++) {
> unsigned int nwoken = 0;
> struct timeval start, end, runtime;
> + u64 runtime_us;
>
> /* create, launch & block all threads */
> block_threads(worker, cpu);
> @@ -211,14 +212,15 @@ int bench_futex_wake(int argc, const char **argv)
> params.nwakes, futex_flag);
> gettimeofday(&end, NULL);
> timersub(&end, &start, &runtime);
> + runtime_us = (u64)runtime.tv_sec * USEC_PER_SEC + runtime.tv_usec;
>
> update_stats(&wakeup_stats, nwoken);
> - update_stats(&waketime_stats, runtime.tv_usec);
> + update_stats(&waketime_stats, runtime_us);
>
> if (!params.silent) {
> printf("[Run %d]: Wokeup %d of %d threads in %.4f ms\n",
> j + 1, nwoken, params.nthreads,
> - runtime.tv_usec / (double)USEC_PER_MSEC);
> + runtime_us / (double)USEC_PER_MSEC);
> }
>
> for (i = 0; i < params.nthreads; i++) {
> --
> 2.43.0
>
next prev parent reply other threads:[~2026-10-05 23:54 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-26 19:03 [PATCH 0/8] perf bench futex: Fix several bugs and bad inputs Michal Pluta
2026-09-26 19:04 ` [PATCH 1/8] perf bench futex: Retry futex_wait() when interrupted by a signal Michal Pluta
2026-09-26 19:13 ` sashiko-bot
2026-10-05 23:49 ` Namhyung Kim
2026-09-26 19:04 ` [PATCH 2/8] perf bench futex: Set the number of hash buckets in futex wake Michal Pluta
2026-09-26 19:09 ` sashiko-bot
2026-09-26 19:04 ` [PATCH 3/8] perf bench futex: Use the whole timeval for elapsed times Michal Pluta
2026-09-26 19:11 ` sashiko-bot
2026-10-05 23:54 ` Namhyung Kim [this message]
2026-09-26 19:04 ` [PATCH 4/8] perf bench futex: Reject invalid -q, -f and -b values Michal Pluta
2026-09-26 19:10 ` sashiko-bot
2026-09-26 19:04 ` [PATCH 5/8] perf bench futex: Stop when futex_wake() fails in futex wake Michal Pluta
2026-09-26 19:10 ` sashiko-bot
2026-09-26 19:04 ` [PATCH 6/8] perf bench futex: Use a 64-bit operation counter in hash and lock-pi Michal Pluta
2026-09-26 19:10 ` sashiko-bot
2026-09-26 19:04 ` [PATCH 7/8] perf bench futex: Clean up two nits in futex hash Michal Pluta
2026-09-26 19:10 ` sashiko-bot
2026-09-26 19:04 ` [PATCH 8/8] perf bench futex: Fix wording in futex bench messages Michal Pluta
2026-09-26 19:13 ` sashiko-bot
2026-10-05 23:57 ` Namhyung Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=asQ4sju-WXehW8oP@google.com \
--to=namhyung@kernel.org \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=andrealmeid@igalia.com \
--cc=bigeasy@linutronix.de \
--cc=dave@stgolabs.net \
--cc=dvhart@infradead.org \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=michalpl2003@gmail.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.