From bf37ac77754ef525f93e3746508014d281bef3e0 Mon Sep 17 00:00:00 2001 From: Nicolas Bouton Date: Tue, 5 May 2026 13:27:35 +0200 Subject: [PATCH] lat_mem_rd: add count override Add a -c option to lat_mem_rd so the user can limit dynamically the number of instructions executed per iteration. Additionaly, this patch keeps the existing default behavior for normal runs. This changes allow to perform the same amount of instruction until the default count (computed with the size of the array currently tested and the stride) reach the count limit given by the user. * src/lat_mem_rd.c, src/lib_mem.h: Here. Signed-off-by: Nicolas Bouton --- src/lat_mem_rd.c | 35 +++++++++++++++++++++++------------ src/lib_mem.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/lat_mem_rd.c b/src/lat_mem_rd.c index 9a4d896..999aac1 100644 --- a/src/lat_mem_rd.c +++ b/src/lat_mem_rd.c @@ -2,8 +2,8 @@ * lat_mem_rd.c - measure memory load latency * * usage: lat_mem_rd [-P ] [-W ] [-N ] - * [-s ] [-e ] [-t [-p ]] - * size-in-MB [stride ...] + * [-s ] [-e ] [-c ] + * [-t [-p ]] size-in-MB [stride ...] * * Copyright (c) 1994 Larry McVoy. * Copyright (c) 2003, 2004 Carl Staelin. @@ -19,9 +19,12 @@ char *id = "$Id: s.lat_mem_rd.c 1.13 98/06/30 16:13:49-07:00 lm@lm.bitmover.com #include "bench.h" #define STRIDE (512/sizeof(char *)) #define LOWER 512 +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif void loads(size_t len, size_t range, size_t stride, int parallel, int warmup, int repetitions, - size_t chase_pagesize); + size_t chase_pagesize, size_t count_limit); size_t step(size_t k); void initialize(iter_t iterations, void* cookie); @@ -64,9 +67,10 @@ main(int ac, char **av) size_t stride; size_t lower = LOWER; size_t end = 0; - char *usage = "[-P ] [-W ] [-N ] [-s ] [-e ] [-t [-p ]] len [stride...]\n"; + size_t count_limit = 0; + char *usage = "[-P ] [-W ] [-N ] [-s ] [-e ] [-c ] [-t [-p ]] len [stride...]\n"; - while (( c = getopt(ac, av, "tp:P:W:N:s:e:")) != EOF) { + while (( c = getopt(ac, av, "tp:P:W:N:s:e:c:")) != EOF) { switch(c) { case 't': fpInit = thrash_initialize; @@ -93,6 +97,12 @@ main(int ac, char **av) case 'e': end = atoi(optarg); break; + case 'c': + char *endptr; + count_limit = (size_t)strtoul(optarg, &endptr, 10); + if (optarg[0] == '-' || *optarg == '\0' || *endp != '\0' || errno == ERANGE) + lmbench_usage(ac, av, usage); + break; default: lmbench_usage(ac, av, usage); break; @@ -117,7 +127,7 @@ main(int ac, char **av) fprintf(stderr, "\"stride=%d\n", STRIDE); for (range = lower; range <= end; range = step(range)) { loads(len, range, STRIDE, parallel, - warmup, repetitions, chase_pagesize); + warmup, repetitions, chase_pagesize, count_limit); } } else { for (i = optind + 1; i < ac; ++i) { @@ -128,7 +138,7 @@ main(int ac, char **av) fprintf(stderr, "\"stride=%d\n", stride); for (range = lower; range <= end; range = step(range)) { loads(len, range, stride, parallel, - warmup, repetitions, chase_pagesize); + warmup, repetitions, chase_pagesize, count_limit); } fprintf(stderr, "\n"); } @@ -149,7 +159,7 @@ benchmark_loads(iter_t iterations, void *cookie) struct mem_state* state = (struct mem_state*)cookie; register char **p = (char**)state->p[0]; register size_t i; - register size_t count = state->len / (state->line * 100) + 1; + register size_t count = state->count; while (iterations-- > 0) { for (i = 0; i < count; ++i) { @@ -165,10 +175,10 @@ benchmark_loads(iter_t iterations, void *cookie) void loads(size_t len, size_t range, size_t stride, int parallel, int warmup, int repetitions, - size_t chase_pagesize) + size_t chase_pagesize, size_t count_limit) { double result; - size_t count; + size_t count_limit; struct mem_state state; if (range < stride) return; @@ -183,7 +193,8 @@ loads(size_t len, size_t range, size_t stride, exit(1); state.pagesize = chase_pagesize; } - count = 100 * (state.len / (state.line * 100) + 1); + default_count = (state.len / (state.line * 100) + 1); + state.count = count_limit ? MIN(count_limit, default_count) : default_count; #if 0 (*fpInit)(0, &state); @@ -204,7 +215,7 @@ loads(size_t len, size_t range, size_t stride, /* We want to get to nanoseconds / load. */ save_minimum(); - result = (1000. * (double)gettime()) / (double)(count * get_n()); + result = (1000. * (double)gettime()) / ((double)state.count * (double)get_n() * 100.); fprintf(stderr, "%.5f %.3f\n", range / (1024. * 1024.), result); } diff --git a/src/lib_mem.h b/src/lib_mem.h index 5268515..20517e4 100644 --- a/src/lib_mem.h +++ b/src/lib_mem.h @@ -31,6 +31,7 @@ struct mem_state { int width; size_t len; size_t maxlen; + size_t count; size_t line; size_t pagesize; size_t nlines;