Monday, 15 July 2013

Processing Integers On 32 Bit vs 64 Bit Cpu

A number of questions that need to be answered when upgrading from 32 bit to 64 bit Cpu processing.
Q: Does a 64 bit integer on a 64 bit Cpu work slower than a 32 bit integer on a 32 bit Cpu?
A: Not for most operators. Operators like add and subtract and shift seem to be about the same. The exceptions are operators involving division. A 64 bit integer divide on a 64 bit Cpu is way slower than a 32 bit divide on a 32 bit Cpu.
Q: Is processing a big array of 64 bit integers on 64 bit Cpu slower than processing an array of 32 bit integers on a 32 bit Cpu?
A: Yes. 64 bit integers use more memory, so to get from one end of an array to the other will read in more memory from the RAM, and if you are writing back to the values then it will transfer more memory back to the RAM since a 64 bit integer is twice as large as a 32 bit integer. However processing an array of 32 bit integers on a 64 bit Cpu transfers just the same amount of memory as processing a 32 bit integer array on a 32 bit Cpu.
Q: Why did all the C++ compilers choose LLP64 and LP64 as the default model, which keeps int as 32 bits on 64 bit Cpu?
A: Mostly to keep compatibility with existing code but also because it requires less space in memory. Naive programs that just use int for everything in the ILP64 model will have to deal with more bytes being used up in the Cpu cache as a consequence of using 64 bit integers for everything. In most existing programs almost everything to do with lists and arrays and chunks of memory is in a context where the addressable indexes into the memory can all be contained within 32 bits. You will not find any 32 bit programs that use strings that are longer than 32 bits can store for example.

Q: Which integer type should be used for list indexing in C++ on 64 bit Cpu? 
A: For lists it is unlikely that you will ever need more than 2.4 billion items, at least with current systems, even 64 bit ones, so 32 bit is in 99.99% of cases ideal, since the extra 32 bits of a 64 bit are not needed. However progress is always going on so you might want to consider making a type called "ix_t" and using that instead for your list length fields and to index the lists. The problem is not just the indexing but if you had hundreds and thousands of objects in memory all of type "TList", then using a 64 bit integer would in all normal cases simply be unused 4 bytes on each list object.

Q: Which integer type should be used for array indexing on 64 bit Cpu?
A: This is a tricky question, since with array memory you can easily imagine people allocating large chunks of memory that cannot be indexed by a 32 bit int, for example, a 5Gb chunk of memory. However the practice of allocating very large chunks of memory is not yet common, and would be very rare in the overall usage of arrays in a program. Using a 64 bit integer for indexing does not make so much sense either. So if you are hyper optimizing some code, then for most arrays use a 32 bit integer and then a 64 bit integer only where you need it.

Otherwise the best thing to do is to benchmark your machine yourself. I have made a benchmark tool that builds in Codeblocks, and the download comes with a decent set of results for a Core 2 Duo Cpu.

No comments:

Post a Comment