I was flipping through a C++ slideshow on efficiency when I came across one which stated,
Prefer 32-bit ints to all other sizes, because (for one reason), 8 and 16-bit computations use conversion to 32-bits and back.
( source:
http://image.slidesharecdn.com/main-slides-121220010501-phpapp01/95/slide-21-638.jpg?1355987208 )
I figured this just meant that int8 and in16 types are copied into a CPU register (assuming 32-bit arch) for operations, and then stuffed back into memory.
I got curious, and hacked around with some assembly and confirmed that this was the case, even for 32-bit types, they always get copied into a register, and copied back to memory later.
So I got even more curious, and wondered... "is this even necessary?"
I wrote an 'optimized' version of this code in assembly, and it seems to do exactly what it did before, just with fewer operations.
Even with various g++ optimization levels with the -O# option, it still used the register as an intermediary.
Why?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
#include <stdio.h>
int main ( void ) {
/**/ // Original C++ Code
volatile unsigned int ui=2147483647; // max value
ui++; // overflow by one
printf("%d\n",ui);
return 0;
/**/ // Copy-Pasta assmebly from `g++ -S try.cpp`
volatile unsigned int ui;
asm("movl $2147483647, 28(%esp)");
asm("movl 28(%esp), %eax");
asm("addl $1, %eax");
asm("movl %eax, 28(%esp)");
printf("%d\n",ui);
return 0;
/**/ // Optimized assembly, does not copy ui to/from register for ui++
volatile unsigned int ui;
asm("movl $2147483647, 28(%esp)");
asm("addl $1, 28(%esp)");
printf("%d\n",ui);
return 0;
}
|