Instantiating a template function in all M * N combinations

Viewed 135

Imagine I have M methods that I want to time, along with N timing methods (let's call them clock implementations)1. The exact details aren't too important here, but I'm mentioning it so I can give a concrete example.

Now let's say I have a templatized timing method like so:

typedef void (bench_f)(uint64_t);

template <bench_f METHOD, typename CLOCK>
uint64_t time_method(size_t loop_count) {
  auto t0 = CLOCK::now();
  METHOD(loop_count);
  auto t1 = CLOCK::now();
  return t1 - t0;
}

Basically it brackets the call to METHOD with calls to CLOCK::now() and returns the difference. Note also that METHOD is not passed as a function pointer, but rather only as a template argument - so you get unique instantiations for each method, rather than one and then an indirect call through a pointer.

This works well for my case because both of the clock calls and the method under test are direct static calls (i.e., something like call <function address> at the assembly level).

Now I have N methods I want to test (perhaps 50) along with M clock methods (perhaps 5). I want to actually instantiate, at compile time, all M * N methods, so that I can call all the test methods with a specific clock implementation.

Now the "standard" way to do this would just to pass a function pointer (or class implementing a virtual function) for both the method under test and the clock implementation, at which point I'd only need a single time_method method and can create whatever combination I want at runtime. In this particular case, the performance impacts of the indirect calls are too much, so I want template instantiation and I am willing to pay the resulting binary bloat (e.g., M * N = 250 instantiated combinations with my numbers).

At runtime I want to get a list of N method combined with a particular clock, for example.

I am fine explicitly listing all N method and all M clocks, but I don't want to write out the M * N instantiations (DRY and all that).


1 I'm using the word clock pretty loosely here - some of the "clocks" may in fact measure aspects unrelated to time, such as heap memory use, or some application specific metric.

2 Answers
Related