Here\'s some code (full program follows later in the question):
template
T fizzbuzz(T n) {
T count(0);
#if CONST
const T d
The difference in speed is caused by the compiler not knowing if "div" will change value. When it is non-const, it is treating it like a variable being passed in. It could be anything, and so the compiler will use an instruction that divides two variables - idivl. When you say that it's const, the compiler is free to treat it exactly as if you'd typed:
if (i % 3 == 0)
I'm kind of surprised that it didn't use bitwise AND(&).
The WrappedInt isn't being optimized because, well, its not an int. Its a class.
Something that you could do is incorporate fizzbuzz into WrappedInt.
Is there a known way of wrapping an int such that the compiler can discard the wrapping when optimising?
Try passing WrappedInt
by value. Then WrappedInt
s can be passed in registers. Pass-by-const-reference sometimes forces gcc to fall back to the stack for argument passing.
About the int
vs const int
slowdown, I can only speculate that GCC is trying to play it safe in the face of aliasing. Basically, if it cannot prove that div
is not an alias for another, more accessible variable, it cannot turn it into a constant. If you declare it const, GCC assumes it's not aliased and performs the conversion into a constant. Apart from the idivl
, you should also see a memory fetch, once, when entering the function, as opposed to immediate values being used for the const
case.
Try combining const int v
in your WrappedInt class with const T
in your fizzbuzz function and see if the compiler can optimize that.
By declaring const int
you've created a special case - a compile time constant. The compiler knows what the value is, and can optimize it more heavily than a value that could possibly change during the run of the program.
I'm guessing its just the severely old GCC version you are running. The oldest compiler I have on my machine - gcc-4.1.2, performs the fast way with both the non-const and the wrap versions (and does so at only -O1).