C constants defined at join time

I have a VERY performance-sensitive application, and I wonder if I can save some constants for communication. I have a number of global constants that I use (e.g. simulation sizes) that are used by an insane amount. I tried changing them from constants to variables, and performance dropped dramatically. Thus, I created a somewhat confusing system that assigns constants from the configuration file and builds the executable file explicitly for the requested set of parameters. Thus, I would like to minimize how many things I rebuild for each parameter change.

The question is, can I precompile some of my objects and put the values ​​during the link. The most likely implementation I can think of is to include these constants in const arguments to the function they need, and we hope that optimizing the compiler / linker will lead to the same performance as hardcoded as #define constants Any suggestions on how to make this work?

(You know how people say such things, β€œbut it doesn’t matter if you don’t do it billions of times in scientific computing on a cluster?” β€œI’m a guy doing it billions of times in scientific computing on a cluster. Yes, I will also test anything before fully implementing it.)

+4
source share
3 answers

Assuming gcc, you can declare constants with an external link, put them in your source file, and compile and link to optimize the connection time .

In the case of clang, I recommend a similar approach, but instead of the usual LTO compilation with bit code using -emit-llvm -c and only compiling to native code as the last step in linking.

In addition, you can leave your code as is (i.e. use preprocessor definitions) and trust ccache to avoid unnecessary recompilation.

+4
source

You will need to analyze why you have a slowdown with variables, perhaps best of all by looking at the collector, which is created, usually with the -S option to the compiler.

There can be many reasons to speed things up if you have constants:

  • Small integer constants can go to build operations
  • The compiler can perform a loop reversal
  • there may be special arithmetic tricks if the constant is a power of 2

On the other hand, you can slow down if you only pass a pointer to const in your function, and the compiler cannot rule out that your const qualified object is smoothed. const only says that you have no right to change the value, but the compiler cannot know if it changes unexpectedly. Declaring a pointer with restrict can help here.

So, identify the problem points, compare them in assembler with two different versions (constants and const qualified variables) and try to find the reason for the slowdown.

Use inline to troubleshoot in-place optimized issues.

If nothing else helps, and if you manage to localize it, you might even consider writing a script by creating this function with literal constants and compiling this small piece of code before each run. If your runs are long, it may well pay off for a short compilation and reuse.

+3
source

You can, but it will not help you. The profit you get from recompiling with different constants is that the compiler knows the values ​​at compile time and can optimize based on this. If you create an object and associate it with persistent data later, it will be the same as using variables, and you will suffer from a performance hit.

It seems like an interesting problem, now there are few opportunities for real optimization of hairy men :)

+2
source

Source: https://habr.com/ru/post/1402017/


All Articles