4 ms·
As an anecdote of just how powerful this can be, I once wrote a prototype of a simulation (written in C) that used a lot of integer divisions and needed to be r
by dpwm 9y ago
As an anecdote of just how powerful this can be, I once wrote a prototype of a simulation (written in C) that used a lot of integer divisions and needed to be run many times with different parameters.
As a quick and dirty hack that took about half hour to implement, I decided to just have the program as a template string and the parameters be substituted in by a python script that called GCC. To the amazement of a very sceptical friend, the result was a 5x speedup.
A lot of this speedup was consistent with replacing the integer divisions with multiplicative inverses, but also merging constants in a way that would have made things quite unreadable. I was quite impressed with how far GCC had gone.
Considering each instance of this simulation ran for tens of minutes, it was well worth compilation time of a few seconds. It kept the code really simple, too.
- contravariant 9y agoWhat made you choose a python script rather than C++ templates or the C preprocessor?
- mmlb 9y agoThe way I read GP, the python script can very well do the equivalent of gcc -DPARAM=42 -o binary-param=42 && ./binary-param-42. edit: oh nm, reread GP...
- dpwm 9y agoPretty much, except with more parameters taken from a file. The substituting in of parameters was done in Python just so that I could manually check the output for a few cases. I think if I had to do something similar again today, any script would output a shell script that used command line macro definitions. That didn't really occur to me at the time.
- dpwm 9y agoIt was a hack. I knew the C compiler could do these optimizations at compile-time that would take me longer to implement at run-time and would probably introduce mistakes. I could well have used the C-processor, but the parameters needed to be taken from a file for each program. The simulation was run about 100 times with different parameters. Instead of taking about an hour each they instead took about 12 minutes each, with the only difference being baking in all the parameters as constants and letting GCC do the rest.
- ChrisRackauckas 9y agoThat's pretty much what you get with Julia, except it will also do interprocedural optimization (i.e. inline constants and functions across calls) on v0.7. All without playing with templates. I'll gladly pay a 1 second JiT lag for a few days off my computation. At the same time, I don't have screw around with templates.
- dpwm 9y agoYour comment has taken me from having mixed feelings about Julia to making me convinced I want to try Julia for something numerically intensive that I would be inclined to turn to C for.
- jey 9y agoEven better, Julia code is super high-level and readable. And you can just drop down to C using the builtin "ccall" facility. Julia's type system is designed for excellent interop with the C ABI.
- pkaye 9y agoYou should check out this presentation done by Matt Godbolt about compiler internals. He talks about what kind of optimizations are being done by GCC and Clang. Pretty amazing stuff. For example, the compiler will figure out you are trying to write a pop count in high level code and replace it with a single popcount instruction. https://www.youtube.com/watch?v=bSkpMdDe4g4 https://www.youtube.com/watch?v=bSkpMdDe4g4
- mpweiher 9y agoAmazing, yes. Scary, also. If you're going to figure this out, please output a warning and ask me to call the optimized intrinsic or something.
- bigcheesegs 9y agoWhy? The intrinsics aren't portable, the other code is.
- dpwm 9y agoEven with intrinsics that do have a degree of portability, I prefer the more explicit form of the bit counting just for readability. Nobody has to learn what popcnt means. These optimizations really mean that as software writers we can declare our intent and have the compiler do safe optimizations. It seems like these optimizations of Clang are also quite insensitive to the many different ways of writing the same thing that C++ has earned notoriety for.
- mpweiher 9y ago> I prefer the more explicit form Huh? It's not explicit, the purpose is implicit. You are writing down an algorithm that implements a popcount algorithm. The compiler than has to infer the fact that you actually wanted popcount (maybe you just wanted to waste a bit of time in a timing loop?) and then substitute something based on that inference. I am all for it being explicit, i.e. some library function that has a name that somewhere mentions "popcount" or some such. Then have the compiler generate whatever code it needs for that function.
- Doxin 9y agoNext time you're considering something like this, have a look at D: It has nearly the same syntax as C but with some seriously awesome power features. You could've easily written the whole python/c mess entirely in D, generating the code to compile at compile time e.g. from a config file.