But let's assume that the operation is not quite so trivial like here, then this structure would be a prime example where each loop operation is independent from each other, so you can sum a vector in parallel (=SIMD) and then sum the vector once in the end.
Also, since we're obviously not using any compiler optimizations, you can unroll the loop, which reduces per-iteration loop overhead (the conditional jump) and in such a simple case as here is bound to give a nice boost.
Anything that is easily expressed as a set of simple recurrences that can be solved, it'll solve.
or
s = NUMBER
now <rant> IMO what the parent commenter was trying to say is often this punchline about premature optimizations used as catch-all justification for all the convenience/expediency related decisions taken. & also it just works well to create future work. unfortunately that never gets scheduled as I have seen management time frame shrink too. almost everyone is in quick & dirty 'working' version to book a success and move on. with this culture if you try to push resolving these 'technical debt' type issues you are just perceived as a downer. </rant>
But assuming his CPU takes one cycle for an addition and one cycle for a conditional jump, his CPU only needs to run at 1GHz to achieve his result.
Given that branch prediction should be nearly perfect for such a simple and short loop, modern x86 CPUs doing at least 4 integer additions per cycle, and typical CPU speeds in the range of 2-4 GHz, a properly optimized version should be nearly an order of magnitude faster.
So either more aggressive compiler flags and maybe SIMD intrinsics, or hand written assembly (easy here, not so easy in the real world)
Huh?
>NUMBER = atoi(argv[1]);
argv is populated at runtime based on what the OS passed you.
But you are right if you meant that my statement is too strong: you can't do arbitrary loop unrolling. You can jump to a loop that's unrolled once if the number is even, etc.
There are certainly also optimizers that will just output the input without any loop, but that's beyond anything I would expect of a current production compiler.
s = i = atoi(argv[1]);
Now the loop is gone.Edit: This will still happen even if you're doing other stuff in there. GCC will attempt to inline and optimize like this. If it is impossible then you will see a loop with most of the stuff factored out of it.
But if you had to do it manually, loop unrolling and SIMD instructions (although not part of standard C) would be good bets and can probably get you an order of magnitude.
sub rsp, 8
mov rdi, QWORD PTR [rsi+8]
mov edx, 10
xor esi, esi
call strtol <-- atoi
xor eax, eax <-- zero return value
add rsp, 8
ret <-- return from main
Interestingly enough it does not elide the entire function body. 000000000400400 <main>:
400400: 48 83 ec 08 sub $0x8,%rsp
400404: 48 8b 7e 08 mov 0x8(%rsi),%rdi
400408: ba 0a 00 00 00 mov $0xa,%edx
40040d: 31 f6 xor %esi,%esi
40040f: e8 dc ff ff ff callq 4003f0 <strtol@plt>
400414: 31 c0 xor %eax,%eax
400416: 48 83 c4 08 add $0x8,%rsp
40041a: c3 retq
40041b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Which I'm not a fan of. I've always wanted "add (store), (get)" but could never get that."O(0)" is pretty much meaningless.