This is going to depend on the implementation of the log() functions in the C library, compiler version, hardware architecture, and so on. Anyway, below I’m using GCC 4.4 on x86-64 with glibc 2.11.
Changing the example so that I add a line
cout << "sum=" << sum << endl;
which prevents the compiler from optimizing away the log() calls, as I mentioned in a comment, I get the following timings (whole seconds only, -O2):
- log: 98s
- log2: 105s
- log10: 120s
These timings seem roughly consistent with the -O0 and -O1 timings in the original post; at higher optimization levels the log evaluations are optimized away, hence the -O2 and -O3 results are so different.
Furthermore, looking at the log example with the “perf” profiler, the top 5 offenders in the report are
# Samples: 3259205
#
# Overhead Command Shared Object Symbol
# ........ .............. ......................... ......
#
87.96% log /lib/libm-2.11.1.so [.] __ieee754_log
5.51% log /lib/libm-2.11.1.so [.] __log
2.88% log ./log [.] main
2.84% log /lib/libm-2.11.1.so [.] __isnan
0.69% log ./log [.] log@plt
Except for main, all the other symbols are related to the log() call. Summing up these, we can conclude that 97% of the total runtime of this example is spent in log().
The implementation of __ieee754_log can be found here in the glibc git repo. Correspondingly, the other implementations are: log2, log10. Note that the previous links are to the HEAD versions, for released version see their corresponding branches