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?"
With linux on sparc64, typical applications are 30% slower when running in 64bit userland mode as opposed to 32bit userland mode. There are of course exceptions...
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 ,
The poster named one point: mapping large files.
Using mmap() for certain kinds of I/O is very, very useful in performance-sensitive applications. Using POSIX I/O (i.e. read(), write() and its relatives) means that your data must go through memory twice: once from disk into the buffer/page cache and then once again into userland. Memory-mapped I/O effectively unifies the two, saving on precious memory and memory bandwidth.
sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
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
I believe that the 64-bit capable MIPS architecture found it's biggest success in the embedded processor market. From the wikipedia entry:
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.
Java does not care about memory limits, the JVM does. The stock Sun JVM for x86 machines will address a maximum of 3-4 GiB (dependent on operating system). However, the IBM JVM on an AIX machine has no practical limit and can easily access >16 GiB memory, if available. If a JVM is so designed, there is no reason a Java program can access as much memory as a program written in C.
I run very large simulations on various platforms, and some of my simulations have to be run on a 64-bit machine because of the memory requirements. Sun's Java forums have several posts asking for various maximum heap (maximum memory accessable) for various platforms and you can find more exact numbers for specific platforms and operating systems there.
An object is an object, not a pointer. However, objects are accessed through a reference, which in implementation, is typically a pointer.
That's not true!!
When you create an object in Java, you are, in a sense, creating a pointer. As a matter of fact it's easy to make a linked list or a binary tree with Java, the same way you do in C. Just because it's not explicitly called a pointer doesn't mean it isn't used.
Ever heard of a NullPointerException?
"Java doesn't have pointers" is a hype phrase still left over from the Dot Bomb era...
On CPU:s with segments the impact must be much less if even at all. Say for instance that you reside in a 32 bit segment X and 16 bit subsegment Y then you would use 16 bit storage of pointers in RAM even though the CPU constructs the full 64 bit pointer internally by concatenating all the parts from the segment registers with the 16 bit from RAM.
I don't assume any CPU in particular just the principle of segments.
Of course a 64 bit pointer is 2x the size of a 32 bit pointer... 32 bit pointers only need 4 byte alignment, and thus pack nicely. So 64 bit pointers will take twice the cache space.
And... the pointers have to be loaded. It will take more address bits in the instructions to build constants. More cache used.
It is NOT highly likely that 64-bit alignment is done when optimizing. In fact, that's just wrong.
Yes, cache performance suffers.
Just another "Cubible(sic) Joe" 2 17 3061
A few years back I did a test with a server which store state information (I will not bore you with the details). I did some performance test on both the 32-bit version and the 64-bit version. Same source code. Same test data. Same configuration. On HP-UX 11.0 PA-RISC with the aCC compiler.
The 64-bit version used about 15% more memory than the 32-bit version. But it was also 20% percent faster. That still puzzles me, because the server does not perform any 64-bit operations.
They usually call them "references", but names like NullPointerException give the game away...
Yes, it's true that Java's pointers don't behave quite the same way as C's pointers, but then they don't behave like C++'s references either. It's a different language.
If you meant that you don't do pointer arithmetic, you'd be right, there's none of that available to users in Java, and that's mostly a good thing.
Shame your Java apps use 16-bit characters, when Unicode needs more... maybe you could switch to a language better suited to modern tasks such as I18N. C or C++ might handle that need just fine, with wchar_t typically being 32-bits.
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.
Cyber 180