On 11/08/13 02:54, Oliver Kullmann wrote:
For general enligthenment, could you quickly explain what "reduce the
loop" means? One can of course just get rid off the loop, precomputing
sum, but I guess that's not what you mean? (I don't understand the assembler code.)
With gcc-4.7.1 I get for the following (with a bigger loop):
#include<iostream>
#include<cassert>
template<typename T>
inline T const& max (T const& a, T const& b) { return a<b?b:a; }
int main() {
typedef long long unsigned UInt;
typedef long long Index;
UInt sum = 0;
constexpr UInt n = 100000000000;
for (Index x = 0; x< Index(n); ++x) sum+=max(x,x+1);
assert(sum == (n * (n+1))/2);
std::cout<< sum<< "\n"; // prints "932356074711512064" for 64-bit long long
}
g++ --std=c++11 -Ofast -funroll-loops -Wall Example.cpp
time ./a.out
932356074711512064
real 0m56.278s
user 0m56.126s
sys 0m0.001s
Interestingly, when changing Index to UInt I get
real 1m7.261s
user 1m7.076s
sys 0m0.018s
which is, at least for me, an unexpected difference? (I would have assumed that,
if there is a difference, then Index=UInt should be faster.)
Oliver
Differences between signed and unsigned behavior because with unsigned
there's wraparound,
while in signed the result of an overflow is undefined (and thus the
compiler can make more
assumptions)
However, I do not see that difference when compiling your code (g++ 4.8.1)
$ time ./UInt
932356074711512064
real 1m39.374s
user 1m15.413s
sys 0m0.157s
$ time ./normal
932356074711512064
real 1m46.876s
user 1m4.443s
sys 0m0.207s
$ time ./normal
932356074711512064
real 1m10.107s
user 1m4.360s
sys 0m0.023s
$ time ./UInt
932356074711512064
real 1m29.006s
user 1m15.437s
sys 0m0.067s
$ time ./normal
932356074711512064
real 1m19.602s
user 1m4.383s
sys 0m0.033s
$ time ./UInt
932356074711512064
real 1m17.318s
user 1m15.467s
sys 0m0.010s