2

I am wondering if it is possible to create a clever macro to automatically bench a "process" in C and using only C. Let's say I have a small structure like this:

typedef struct pbench {
  char description[256];
  int nbenchs;
  double times;
} ProcessBench;

And a macro (with get_time() being a function returning a double):

#define BENCH(process, bench_struct, description)      \
  int i;                                               \
  bench_struct.description = description;              \
  bench_struct.nbenchs = 50;                           \
  double start = get_time();                           \
  for (i = 0; i < bench_struct.nbenchs; ++i)           \
    process();                                         \
  bench_struct.times = get_time() - start;

If I'm not mistaken, this macro can be used to benchmark any function with the signature void func() using BENCH(func, func_bench, func_description).

Is there a way I can create some macros like this one to benchmark functions like void func_args(args...), return_type func_return(), return_type func_return(args...) and even small lines of code ?

Kyle Strand
  • 15,137
  • 4
  • 69
  • 154
baptiste
  • 1,037
  • 1
  • 14
  • 29
  • Never use a macro where a function will also work. – too honest for this site Sep 27 '16 at 16:54
  • @Olaf: difficult to do this with a function in C, particularly if the timed function needs to have arbitrary parameters. – Paul R Sep 27 '16 at 17:28
  • @PaulR: I refer to what OP shows. There are no parameters; not sure what he means with "process" in this context, though. Alternatively a mixture of two functions and a macro would be an option. In any case, that macro above does not look very sane to me. – too honest for this site Sep 27 '16 at 17:46
  • 1
    The idea is to have only one function / macro to bench a lot of different stuff on a lot of platforms. I think a macro is a better way to do this. By process I mean any kind of function and at the same time, bench it without polluting the code with benchmarking specific instructions. – baptiste Sep 28 '16 at 07:05

1 Answers1

1

You can just pass the whole function call, including parameters, and ignore any function result, e.g.

#define BENCH(process, bench_struct, description)      \
  int i;                                               \
  bench_struct.description = description;              \
  bench_struct.nbenchs = 50;                           \
  double start = get_time();                           \
  for (i = 0; i < bench_struct.nbenchs; ++i)           \
    process;                                           \
  bench_struct.times = get_time() - start;

BENCH(func(x, y, z), func_bench, func_description)

(Note the small change to the macro - the parentheses have been removed from process.)

Paul R
  • 202,568
  • 34
  • 375
  • 539
  • @baptiste: yes, once of those rare occasions when the solution is simpler than expected. ;-) – Paul R Sep 27 '16 at 16:36
  • 4
    It would be good to enclose it in a block to avoid any clashes with `i`. Even better if it's a [`do { ... } while(0)`](http://stackoverflow.com/questions/154136/why-use-apparently-meaningless-do-while-and-if-else-statements-in-c-c-macros). – Andrea Biondo Sep 27 '16 at 16:56