Created
July 11, 2014 13:46
-
-
Save NobodyOnSE/f859096e4028f3b5bdd2 to your computer and use it in GitHub Desktop.
Discuss some "benchmarking" code for the optimality of prefix vs. postfix incrementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<stdio.h> | |
int main(void) { | |
int i = 5; | |
++i; //or i-- | |
printf("%i", i); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void dummy(int v) {} | |
int main() { | |
int i = 5; | |
dummy(i++); | |
dummy(i); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.text | |
.globl dummy | |
.type dummy, @function | |
dummy: | |
.LFB0: | |
.cfi_startproc | |
pushq %rbp # | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp #, | |
.cfi_def_cfa_register 6 | |
movl %edi, -4(%rbp) # v, v | |
popq %rbp # | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE0: | |
.size dummy, .-dummy | |
.globl main | |
.type main, @function | |
main: | |
.LFB1: | |
.cfi_startproc | |
pushq %rbp # | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp #, | |
.cfi_def_cfa_register 6 | |
subq $16, %rsp #, | |
movl $5, -4(%rbp) #, i | |
movl -4(%rbp), %eax # i, D.1752 | |
leal 1(%rax), %edx #, tmp85 | |
movl %edx, -4(%rbp) # tmp85, i | |
movl %eax, %edi # D.1752, | |
call dummy # | |
movl -4(%rbp), %eax # i, tmp86 | |
movl %eax, %edi # tmp86, | |
call dummy # | |
leave | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE1: | |
.size main, .-main | |
.ident "GCC: (GNU) 4.9.0 20140604 (prerelease)" | |
.section .note.GNU-stack,"",@progbits |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void dummy(int v) {} | |
int main() { | |
int i = 5; | |
dummy(++i); | |
dummy(i); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.text | |
.globl dummy | |
.type dummy, @function | |
dummy: | |
.LFB0: | |
.cfi_startproc | |
pushq %rbp # | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp #, | |
.cfi_def_cfa_register 6 | |
movl %edi, -4(%rbp) # v, v | |
popq %rbp # | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE0: | |
.size dummy, .-dummy | |
.globl main | |
.type main, @function | |
main: | |
.LFB1: | |
.cfi_startproc | |
pushq %rbp # | |
.cfi_def_cfa_offset 16 | |
.cfi_offset 6, -16 | |
movq %rsp, %rbp #, | |
.cfi_def_cfa_register 6 | |
subq $16, %rsp #, | |
movl $5, -4(%rbp) #, i | |
addl $1, -4(%rbp) #, i | |
movl -4(%rbp), %eax # i, tmp84 | |
movl %eax, %edi # tmp84, | |
call dummy # | |
movl -4(%rbp), %eax # i, tmp85 | |
movl %eax, %edi # tmp85, | |
call dummy # | |
leave | |
.cfi_def_cfa 7, 8 | |
ret | |
.cfi_endproc | |
.LFE1: | |
.size main, .-main | |
.ident "GCC: (GNU) 4.9.0 20140604 (prerelease)" | |
.section .note.GNU-stack,"",@progbits |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The point of this is not to prove that postfix increment is less efficient than prefix increment. | |
(This question has no meaning as it either is needed or does get optimized to prefix increment like code!) | |
It is a rather technical one: to criticize the test code in original_test.c which does not use the direct return value of the ++i expression and thereby allows for the return value to be discarded regardless of which increment operator was used. | |
This makes the whole test meaningless because the postfix/prefix difference is not about code before or after the increment but at the increment. | |
I have devised another test case to show what happens if the value is used (the code does nothing in both cases so the program does the same to the eyes of the observer). | |
I used an own function instead of printf to avoid the "ugly" calling convention of printf's varargs. | |
Compiling both c files with gcc -S <file.c> -f -fverbose-asm -O0 resulted in the given assembler files. | |
Comparing these two the code differences (not counting comments)are | |
<pre><code> | |
movl -4(%rbp), %eax # i, D.1752 | |
leal 1(%rax), %edx #, tmp85 | |
movl %edx, -4(%rbp) # tmp85, i | |
</pre></code> | |
for postfix- versus | |
<pre><code> | |
addl $1, -4(%rbp) #, i | |
movl -4(%rbp), %eax # i, tmp84 | |
</pre></code> | |
for prefix-increment. | |
Appart from using another operation to do the adding (leal instead of addl) | |
the postfix increment needs to provide the old value of i as parameter to the dummy function. | |
In both programs the new value of i needs to be stored in i's stack location (aka -4(%rbp)) so they do | |
addl $1, -4(%rbp) | |
or | |
movl %edx, -4(%rbp) | |
Additionally, the postfix version stores the old value of i in eax and passes it to dummy via edi. | |
# Summary | |
Apparently this is a very artificial test and under real circumstances optimizations would be applied. | |
So let me end this before I drain even more time on this topic. :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment