3

I have a condition I do not know at compile time but which once initialized does not change during the program. My program looks something like this

void cond_func(const int cond){
    switch(cond){...}
}

void loop_func(const Some_class& param){
    for(...) cond_func(param.cond);
}

Is branch prediction able to tell that the cond should always evaluate to the same value? Or is it better to write the switch before the loop and then call appropriate functions (which would lead to less readable code with multiple code duplication). Or can I do something to give a compiler hint that this condition will stay constant, like extract the value const int cond = param.cond) before the loop? Would something change if I also pass the const Some_class& param during the loop to some other functions and hence theoretically change value of cond through some weird pointers and/or const_cast (although I`m not)?

My loop is usually millions and more long so I`m not interesting in first few calls to predict the branch but every ms spent in some condition evaluation in every cycle counts....

Michal
  • 671
  • 3
  • 9
  • 22
  • Have a read of: https://stackoverflow.com/questions/30130930/is-there-a-compiler-hint-for-gcc-to-force-branch-prediction-to-always-go-a-certa – Richard Critten Oct 30 '17 at 22:52
  • I read that but I do not know which condition is more likely, I just know it doesn`t change. – Michal Oct 30 '17 at 22:57
  • "extract the value `const int cond = param.cond`) before the loop" is definitely worthwhile, because otherwise the compiler has to worry not only about functions to which you pass `param` which might do a `const_cast`, but also any (non-const) pointers and references to the same `Some_class` object which were made before your `loop_func` was called. If the compiler can't prove there aren't any, it will surely have to re-evaluate the condition each time, and can't do loop/conditional interchange. CPU branch prediction will still help, but not nearly as much as compiler optimizations. – Ben Voigt Oct 30 '17 at 23:26
  • Note that careful use of templates can encourage the compiler to do the interchange. – Ben Voigt Oct 30 '17 at 23:27
  • 1
    @BenVoigt can you please elaborate more on templates usage? – Michal Oct 31 '17 at 15:02
  • I'm also curious to know the best way to do this. One way you could do this is to have an object, with a constructor that takes the conditional variable, then inside the constructor, assign a function to a member variable (callback, function pointer, delegate, etc.). So once this object is constructed, the condition determines what function will be assigned to its member variable. After that, in your critical path, the object will directly use its function pointer to do the correct call. Consider the size of this object for cache-line-fitting purposes.. Anyone know a better approach? – Anton Jan 09 '18 at 07:39

1 Answers1

0

I think checking the condition once and looping millions times beats looping millions and checking every time, even with branch predictions.

Maybe your design is not the best. Switch, loop and call a function with a different argument depending on the switch for example. I can't really say, I don't know what you're doing in there.

karim_g
  • 115
  • 11