Arkady
Arkady

Reputation: 2207

C++ Compile code for all variants of finite number of settings

For example, there is hard logic inside function void Func(long param1, long param2, long param3, long param4, long param5).

It has a lot of statements inside depends on parameters, different checks, calculations depends on combinations and etc.

And that function is called many million times and takes serious amount of execution time. And I'd like to reduce that time.

All parameters are taken from config.ini file, so, they are unknown at compile time.

But I know, that param1 may be in diapason [1..3], param2 in diapason [0..1] and etc.

So, finally, there is maybe 200 combinations of those parameters.

And I'd like my compiler compile separated 200 combination, and at the beginning of run-time, when config.ini loaded, just choose one of them, and avoid run-time calculation of parameter's dependencies.

Is that possible to achieve in C++98? Or in C++11/14?

Upvotes: 1

Views: 57

Answers (2)

Schafwolle
Schafwolle

Reputation: 531

I don't know if you have considered this but you could load the config at the beginning, calculate your 200 possible solutions and put them into a lookup table. This depends on the storage you can spare. Since your number of combination seems to be small, this should be no problem. You simple merge the parameter to an integer. E.g. ( x =[0...3]; y = [0...1]) => use first 2 bit for x 3rd bit for y and so on. Calculate all possibilities using loops. And store the result inside of an array. If you don't own parameter with the power of two. You can simply multiply the possibilities. E.g x =[0...3] y =[0...5] z =[0...2] => idx = x + y*(possibilites of x = 4) + z * (pos. x = 4) * (pos. y = 6)

Upvotes: 0

Marko Popovic
Marko Popovic

Reputation: 4153

It is certainly possible to do this using templates, since templates can have integers instead of type parameters. For instance, the following function

template <int iParam1, int iParam2>
int sum()
{
    return iParam1 + iParam2;
}

is a function in which iParam1 and iParam2 are fixed values for a specific template instantiation. For example, function sum<1, 2> is a function that always returns 3.

In you case, define Func with this prototype:

template <long Param1, long Param2, long Param3, long Param4, long Param5>
void Func()

Then, create a std::map that maps a combination of parameters to a function in which these parameters are fixed. Something like this:

using ParamCombination = std::tuple<long, long, long, long, long>;

using ParamsToFunction = std::pair < ParamCombination, std::function<void()> >;

std::map< ParamCombination, std::function<void()> > map =
{
    ParamsToFunction(std::make_tuple<long, long, long, long, long>(1, 2, 2, 2, 2), Func<1, 2, 2, 2, 2>),
    ...
    // This map will contain pairs of all possible parameter combinations
    // and their corresponding functions. This is a long list but it can be
    // easily generated using a script.    
};

These function will have all the benefits of compile time optimizations. Finally, during runtime, all you need to do is create a tuple that represents a parameter combination and call the function that this tuple maps to:

auto comb = ParamCombination(1, 2, 2, 2, 2);
map[comb](); // function call

Upvotes: 2

Related Questions