I have a VERY performance-sensitive application, and am curious about if I can save some constants for linking. I have a number of global constants that I am using (simulation dimensions, for example), which are used an insane amount. I tried changing them from constants to variables, and the performance dropped dramatically. Thus, I have created a somewhat convoluted system which assigns constants from a configuration file, and builds an executable explicitly for the requested set of parameters. Thus, I would like to minimize how much stuff I rebuild for each parameter change.
The question is if I can pre-compile some of my objects, and put the values in at link time.
The most likely implementation I can think of for this would be to include those constants as const
arguments to the function that needs them, and hope that the compiler/linker optimization results in the same performance as having hardcoded them as #define
constants. Any suggestions about how to make this work?
(You know how people say things like "but this doesn't matter unless you're doing this billions of times in scientific computing on a cluster"? -- I'm the guy doing it billions of times in scientific computing on a cluster. Yes, I also will benchmark anything before fully implementing it.)
Assuming gcc, you could declare the constants with external linkage, put them into their own source file and compile and link with link-time optimizations.
In case of clang, I recommend a similar approach, but instead of using regular LTO, compile to bitcode using -emit-llvm -c
and only compile to native code as a last step when linking.
Also, you could leave your code as-is (ie using preprocessor definitions) and trust in ccache to avoid unnecessary recompilation.
You'd have to analyse why you have the slowdown with variables, probably best by looking into the assembler that is produced, usually this is with option -S
to the compiler.
There may be a lot of reasons for the speedup if you have constants:
You can get slowdown on the other hand if you only passing pointer to const
to your function and the compiler can't exclude that your const
qualified object is aliased. const
only says that you don't have the right to change the value but the compiler can't know if it changes unexpectedly. Here declaring the pointer with restrict
might help.
So identify the trouble spots, 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 get the trouble spots neatly optimized in place.
If nothing else helps, and if you happen to localize it nicely you might even consider to write a script producing that function with literal constants and compile that little piece of code before every run. If your runs are long, there may well be a pay off for short compilation and relinking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With