Effect of Using 64-bit Pointers?
An anonymous reader queries: "Most 64-bit processors provide a 32-bit mode for compatibility, but 64-bit pointers are becoming essential as systems move beyond 4GB of RAM. Also, the large virtual address space is very useful for several reasons - allowing large files to be memory-mapped, and allowing pages of memory to be remapped without ever requiring the virtual address space to be defragmented. However, 64-bit pointers take up twice as much memory, which immediately affects memory footprint. This is especially an issue on embedded platforms where RAM is at a premium, but even on systems where RAM is plentiful and cheap the extra memory footprint reduces cache performance. Have Slashdot readers done any research into the actual effect of using 64-bit pointers in a 'typical' application? What proportion of a real program's data is actually pointers?"
Have Slashdot readers done any research into the actual effect of using 64-bit pointers in a 'typical' application?
none whatsoever.
What proportion of a real program's data is actually pointers?
none whatsoever.
oh... i use java.
MARIJUANA, SHROOMS, X: ONLINE?! - E
Huh? On systems where RAM is at a premium, I don't see the point of using or having 64-bit pointers.
"Send an Instant Karma to me" - Yes
By the way, the limit was from physical slots - 8 and a 2GByte DIMM memory limit, increase either of those and guess what.
Now each "process" on our box could only address 4 Gbyte of that memory, but that was a completely different question (and in fact limited by the libraries that were used - again a different story)
I remember these conversations when the 32 bit world came around - what do you mean I have to put 4 bytes into the processor. End result is that the code is a little larger, and a little slower - and Moore's law marches on and we don't even notice
I have mod points and I am not afraid to use them
There's an interesting discussion of 64-bit immediate values at the following link: 64 bit immediates in Python
If we are already using 64 bits for our pointers, a virtual machine has the potential of exploiting a the pointer's larger footprint for other immediate values. I'm not as crazy about using the MSB of the pointer for indicating an immediate as Ian Bicking appears to be, I'd recommend using the LSB since it's easier to bias any object to an even address than halve the potential addressable space.
Then again, if the potential address space is 2 ** 64, I suppose it's not such a sacrifice.
Weapons of Mass Analysis
You missed a good point in the original question. Even if you have tons of RAM, cache size is not growing as quickly and you will thrash your data cache far more quickly if all your pointers double in size. I don't know if immediate mode addressing instructions are common for 64bit operands but if they are, it could thrash your icache sooner as well.
Bandwidth from memory to cache will also be used by these larger pointers.
OTOH, other than disk controller caches (?), what kind of embedded systems need more than 4GB online simultaneously ?
With modern processors it's not uncommon to require 64-bit or 128-bit memory alignment on data structures to get the best performance. There are even some instructions that *require* such data alignments in order for them to work at all (for example: MMX or SIMD).
Because of these existing data alignment issues, going from 32-bit to 64-bit pointers may have absolutely no impact on a program's memory usage and cache performance. It is highly likely you're already using 64-bit alignment when you enable the compiler's optmizations.
Unless you're building massive linked lists of stuff in a scientific / simulation environment this is probably something not worth worrying about. The efficiency and volume of your actual data will still be the biggest waste of space - and it's not like you won't be able to attach more physical memory onto your new system than the old one.
If it does effect you... you probably already know what you're doing or you've been making very bad assumptions about the size of your variable types.
It's not that 32bit processors are a problem, it's that their virtual address space is not very big. 64bit processors can mmap anything you want, even block devices >> a few terabytes. (So if the HURD ever gets ported to AMD64, they can support filesystems > 2GiB, which they don't last I checked because they mmap the device, and the HURD only runs on i386!)
Being able to mmap anything you want is something you just plain can't do on a 32bit CPU. If you want to write programs that don't worry about address space limitations, you need 64bit. Anything that simplifies programming is good, since programmer time is valuable.
Besides that, even if you have 1GB of RAM on i386, Linux needs highmem support to use it all. (It reserves 3GB of virtual address space for user space, and the kernel maps as much RAM as it can with the address space that's left over after mapping PCI and AGP space. So 64bit is useful even on good desktop machines right now. (using highmem slows the kernel down, so might not even be worth it to map the last ~100MiB if you have 1GiB installed.)
Stupid crap like highmem is exactly why we should be using 64bit CPUs.
#define X(x,y) x##y
Peter Cordes ; e-mail: X(peter@cordes ,
Raymond Chens web log. Lately he's been discussing IA 64 programming. I don't pretend to understand 1/2 of what he's talking about but I thought some of the readers here might be interested in what he has to say.
"For a successful technology, honesty must take precedence over public relations for nature cannot be fooled." -Feynman
There's a lot of modern medical equipment which can definitely use the 4GB. MRI machines, CT scanners, ultrasound machines ("sonographs" if you prefer the term) and so on do tend to chew up memory. Particularly the first two, because you often need to hold whole voxel sets in memory while you compute a bunch of cross-sections at odd angles.
sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
I hate to confirm your self diagnosis, but I have sad news to bear.
If you wish to use memory mapped IO to your file system, which has some good technical properties, you need a pointer with an address range *at least* as large as the largest possible file you might need to access, and preferably as large as the largest file system you intend to mount.
Addressibility and physical storage are somewhat orthogonal. (In theory, there is no difference between theory and practice, in practice there is.)
On a machine with 10G of memory, there is no reason for a process to use 64-bit pointers if the process doesn't require more than 32 bits of addressibility. If you look at Apache in the standard threading model, every request is managed by a different process. I doubt you need 64-bit pointers for *each* PHP instance, regardless of how much physical memory the machine contains.
On the other hand, you might be doing some kind of video stream manipulation on a 10GB file using a machine with only 1GB of physical RAM. You would require the use of 64-bit addressibility for this task if you choose the memory mapped IO model.
So yes, you are retarded, but it could be cured by thinking before you type (the post does mention memory mapped IO). There: ten simple words of advice that should apply to 2^33 members of the slashdot community.
I'd say this isn't a problem, will never be a problem, and the person who posted that initial question really doesn't know shit about embedded.
Embedded devices come in all sorts of varieties from 4-bit to 64-bit, and will do for the foreseeable future. When you're producing X million chips, the software is amortised to basically nothing and the hardware cost becomes the primary concern, so there is no chance that lower-spec chips will ever go away in the future.
So you're not going to be forced to use a 64-bit chip in your design, just because the chip company has stopped selling the lower spec ones. In the PC business this does happen, because there's no demand for older, lower-spec chips. In the embedded market though, the demand is there and will continue to be there, so the situation has not and will not arise.
If your target application needs 64-bit processing, you choose a device that does 64-bit processing, and you choose RAM size to suit. If you don't need it, you don't choose it. Simple.
Someone elsewhere had some questions about internal registers/internal RAM. Well as with all processors, some give you enough registers and some don't. Again, the engineer just has to pick the processor that gives the capabilities they want.
Grab.
Seriously, it is faster. I've been writing in assembly for years, and unless I need a 32 bit pointer, I generally don't use them.
If you're that concerned about performance that you are analysing pointer size, you might as well code in assembly. Yes, 64 bit pointers have a bigger footprint, but we experienced the same problem when we went to unicode strings, 32 bit code, etc...
My advice is this: let the compiler deal with it. Unless you are willing to crank out a lot of hand-coded assembly or are interfacing with hardware, the 32/64 bit pointer question is pretty much moot. As it is, you can't control:
for (int x = 0; x < 256; x++)buffer[x] = 0;
Into something like this:
mov cx,64
mov eax,0
mov si,buffer
cld
rep stosd
Instead of the literal translations of the old compilers:
mov si,buffer
mov bx,0 ; this is the x variable
forlabel@10001:
mov [bx + si],0
mov ax,1
add ax,bx
xchg bx,ax
cmp bx,256
jl forlabel@10001
The former takes 68 instruction cycles, the later takes (6 * 256 + 2) = 1576!
The aforementioned issues have a much bigger impact on performance than pointer size. Given that the memory bus is at least 64 bits wide on anything newer than a pentium, you won't incur a clock cycle penalty for using 64 bit pointers.
The only thing that I would suggest is to watch where you place pointers in structures. For example, when building a linked list, you would want to do something like this:
class link {
link * ptrforward;
link * ptrbackward;
link * ptrdata;
}
rather than:
class link{
link * ptrdata;
link * ptrbackward;
link * ptrforward;
}
Because the processor pulls 64 bits per address accessed, the former structure would have the forward pointer in cache regardless of the pointer size. With the second structure, traversing a list in the forward direction would result in a cache miss on every node visited, regardless of pointer size (This applies only to the x86...).
My experience has been that pointer size is only relevant on truly tiny systems - for example, 16 bit code which has to fit into a few kilobytes. Usually, as programs scale to work with larger datasets, the percentage of memory used for pointers decreases rapidly. You'll find that as data sizes increase, the practical uses for linked structures shrink; locating an element by using a binary search on a sorted array scales much better than a linear search traversing linked list.
The society for a thought-free internet welcomes you.