views:

370

answers:

6

We've started compiling both 32- and 64-bit versions of some of our applications. One of the guys on my project is encouraging us to switch all of our 32-bit integers to their 64-bit equivalents, even if the values are guaranteed to fit in a 32-bit space. For example, I've got a value that is guaranteed to never exceed 10,000 which I'm storing in an unsigned int. His recommendation is to switch this to a size_t so that it expands to 64 bits in a 64-bit environment, even though we'll never need the extra space. He says that using 64-bit variables will speed up the application regardless of the values stored in each variable. Is he right? It's turning out to be a lot of work, and I'm not anxious to put in the effort if it doesn't actually make a difference.

We're using Microsoft Visual C++ 2008. I'm kinda hoping for a more general, platform-independent answer though.

So what do you think? Are we right to spend time changing our data types for performance reasons rather than range reasons?

+18  A: 

I think you have a huge case of pre-mature optimization staring you in the face. Never make micro changes like this in your application until a profiler has definitively told you that it is a source of significant performance problems.

Otherwise you'll spend a lot of time fixing non-problems.

JaredPar
+8  A: 

Well if the 32-bit operations are taking place in 64-bit registers, some extra instructions do need to get emitted to handle things like setting carry/overflow flags, etc. I'd be surprised if you realised any noticeable performance improvement, though. I can all but guarantee there are far worse bottlenecks in your program.

Carl Norum
Is this true on x64? I'm not familiar enough with it at the assembly level to know, but it would be a bit surprising to me. I know the question isn't asking for x64 specifics, but I'm curious to know.
Michael Burr
Hm, that's a good question. I'd have to break out the books and check. As you might imagine, it's never been worth figuring out. I'm *far* more familiar with ARM, and on that architecture, using the native size is a lot better as far as code-gen goes. Working with 8-bit types causes all sorts of extra masking and shifting operations to pop up in the code. That said, it doesn't tend to impact performance in any significant way.
Carl Norum
I also would expect that 32bit operations are made via specific 32bit instructions which take care of the carry/overflow flags. But I don't know!
rstevens
@rstevens, I thought of that too; one of the advantages of having a complex instruction set!
Carl Norum
LOL, I can guarantee there are worse bottlenecks too!
Darryl
+1  A: 

I'd guess (and it's just a guess) that you'll likely see no improvement in performance and may see a slight drop if the amount of memory increase causes some memory access to lose locality of reference and push things out of the cache more often than before.

As JaredPar says, if there's not a factual reason to do this or unless you need the increased range of the larger ints, it's probably a waste of time.

Michael Burr
+2  A: 

The idea that using a 64bit integer vs. a 32bit integer will speed things up is a myth. The more important thing in your code is to use the appropriate types. For instance, when referring to the size of an array or data structure, use a size_t because that's what a size_t is supposed to represent. If you're storing some piece of data, then use an int and not a size_t because that's what an int is meant to describe.

Don't just change everything to size_t because it will "automatically become 64bit" this will result in probably no improvement whatsoever. It will cause larger memory overhead which will probably cause the application to slow down due to cache misses because of the larger memory space. It will also quite possibly cause unexpected bugs.

Jason E
+5  A: 

Firstly, using 64-bit ints instead of 32-bit ints in 64-bit environment will not generally speed-up anything. Depending on the context and on the compiler abilities, this might actually slow things down. Normally, you should prefer using int\unsigned int types for storing integral values in your program, switching to other types only when really necessary. In the end, the definitive answer to the question can only be obtained by an actual experiment, since it depends on too many variables.

Secondly, anyone who advises using size_t for that purpose (as a generic unsigned type) should be immediately denied access to code and sent to take some C/C++ classes before they are allowed to touch the code again.

AndreyT
A counterargument: short / int / long / etc are somewhat risky to use, because their behavior is not guaranteed to be the same on all platforms. For example, if you store store your value as an int, then on some platforms the maximum storable value is (2^31)-1, and on some platforms it's (2^63)-1. In many cases that change in behavior won't make any difference, but in some cases it will, and it's not always obvious up-front which cases are which. Therefore int32_t, int64_t, etc, are preferable since they explicitly define the type's behavior in all cases.
Jeremy Friesner
+2  A: 

Don't do it. It just means that the cpu will not be able to hold as much data in cache and the penalty for going to main memory is a lot higher than most other things.

Simon H.