#57930 - Tomik - Wed Oct 19, 2005 11:07 am
Hi, I just want to know if a char value is faster than an INT ?
I just need 0-127 ! I think CHAR is better, because less memeory, much faster !! is that correct ??
Thomas
#57935 - wintermute - Wed Oct 19, 2005 11:38 am
That's a common beginners misconception.
On most modern systems an int is the fastest type, especially when programming in C/C++ where the compiler inserts code to sign extend smaller types.
#57950 - Palamon - Wed Oct 19, 2005 2:29 pm
So which would be best overall to use in the GBA code? for something that only takes 0-127, INT or CHAR ?
Does it matter which type if you are sending that variable over a game link during a multiplayer mode?
#57953 - NoMis - Wed Oct 19, 2005 2:33 pm
Int will take more space but its much faster because memory reads are done as integer.
When the memory bus is 16 bit wide for example, then always 16 bits are read and if you want a 8bit value you have to extract it from that 16bits after the read is done.
Even more costly is writing back to memory because you have to read the 16bit and put your value in and write back the whole 16bit.
NoMis
_________________
www.gamedev.at - The austrian gamedev site
hde.gamedev.at - The Handheld Dev Env plugins for Eclipse
#57969 - poslundc - Wed Oct 19, 2005 5:53 pm
Palamon wrote: |
So which would be best overall to use in the GBA code? for something that only takes 0-127, INT or CHAR ? |
You will get differing opinions on this.
Mine is that you should use the common typedefs u8, s16, u32, etc. when it's important that the variable in question be specified as having that data width. On the GBA, this mostly means things like the IO registers, data packed either in an array or in a struct that I intend to make an array out of, etc.
In all other cases - and I mean ALL other cases - I use int, which is recognized universally as the "fast generic integer number" data type. I never specify the width of the data type as a means of establishing a minimum/maximum value the variable can hold; that should be checked for using ASSERTs.
Quote: |
Does it matter which type if you are sending that variable over a game link during a multiplayer mode? |
Any data you send over multiplayer will have to be packed as tightly as you can cram it, and you will probably be using variables of specified width to do it. You should not design your generic data model based on how the information will be look like when it's packed to be sent over multiplayer, though.
Dan.
#58037 - sgeos - Thu Oct 20, 2005 11:39 am
int is fast, char is small. Are you having space or speed problems? If the answer is neither, I'd use int.
-Brendan
#58038 - Tomik - Thu Oct 20, 2005 11:45 am
I thought less memory = more speed ...but i think that s wrong !
I will have more speed !!! So I use INT, because a 16Bit Processor and it makes CHAR to INT !! Is that correct ??
Thomas
#58050 - Cearn - Thu Oct 20, 2005 1:46 pm
ARM CPUs are 32 bit, not 16. ints are generally the same size as the processor, meaning that on the GBA ints are 32bit (that's why the typedefs s32 and u32 use ints). The CPU size is also referred to as the 'word' size, and is the preferred size for variables. For bigger variables (if any), you'd have to do things in multiple instructions (like 64bit arithmetic here, or 16bit arithmetic for the 8bit NES). For smaller variables (bytes (8bit) or halfwords (16bit)) you often also need multiple instructions, because you have to ensure that the end result is also still of the right size.
For example, adding two numbers z= x+y.
What happens is that the values for x and y are loaded into CPU registers (32bit), then added, and put back into z. That's the general idea for adding, and indeed most data instructions (subtract, multiply, but also bit operations).
Now, x=255 and y=5 leads to z=260 (= 0x104). Easy. When you're dealing with ints, this works fine, because 260 fits inside 32bit. However, it does not fit inside 8bits! For byte-size variables, the result should actually be the byte of z, which is just 4. As the register that holds the result has the full 260 in it, 2 extra instructions have to be added to zero out the upper bytes of the word. Two instructions may not sound like much, but if you could have been done in a single one, it now takes three times as long.
Code: |
load x, 255
load y, 5
add z, x, y
// these will be extra for bytes to account for byte-overflow
// (this is effectively z&255)
lshift z, z, 24
rshift z, z, 24
|
Another example, copying data.
The basic idea here is load data from source address to register, write data from register to destination. Simple. You can do this with byte copies, which means n loads and stores. However, you can also copy in words (32bit). This time, you only need n/4 loads and stores, because you cover 4 bytes in one go. That's roughly 4 times faster.
Code: |
// copy 4 bytes, via bytes
loadbyte x, [src]
storebyte x, [dst]
loadbyte x, [src+1]
storebyte x, [dst+1]
loadbyte x, [src+2]
storebyte x, [dst+2]
loadbyte x, [src+3]
storebyte x, [dst+3]
// copy 4 bytes, via words
loadword x, [src]
storeword x, [dst]
|
This is why ints are faster than chars (and shorts). The actual times may vary a bit and there are some really nasty snares when it comes to copying, but the general idea stands: if you can, stick to the bit-width of the CPU.
Having said that, there is no reason you can't have global data in bytes, but local variables in ints. Something like:
Code: |
u8 array[256];
void function()
{
int ii;
u32 var;
for(ii=0; ii<256; ii++) // or whatever
{
var = array[0];
// do stuff with var
array[0]= (u8)var;
}
} |
or something like that; it depends very much on what you want to do. For the actual work, you can use the word-sized var, then cast back when you need to store it again.
Oh, and on pain of death: don't ever use non-word variables for loop variables.