3

I just went through a bunch of stack vs heap threads here on Stack Overflow (and other random sites found through Google), and yet I can't find an answer that provides much (if any) depth to the issue of read/write speed (most answers and articles focus on allocation speed).

If I'm writing a C program (in my case, a game) where I'm storing object data in a buffer that's a few kilobytes in size, will it make a difference (in terms of access speed) if that buffer is allocated on the stack or on the heap? Or will the compiler treat a buffer of that size the same either way when it comes to deciding where on the hardware (i.e. cache or RAM) to store it?

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Access to RAM is essentially independent of the address, and the virtual address in your process maps to a random, unknowable physical address anyway. Far more important than the specific location of the memory is the caching behaviour in your memory access patterns. (There's also a synchronisation cost for the allocation itself, but you didn't ask about that one.) – Kerrek SB Dec 04 '14 at 10:52
  • By "memory access patterns" do you mean storing my object data as a struct of a arrays rather than an array of structs (XXXYYYZZZ vs XYZXYZXYZ)? (edit: ah never mind I'm an idiot, just looked it up- you mean the way in which my program is accessing the data... right?) – DudeMan2000 Dec 04 '14 at 11:03
  • @DudeMan2000 struct of arrays and arrays of structs are not the same thing :) But yes, KerrekSB means what you looked up. If you have a 1GB byte array, it matters if you access the whole GB in a loop from start to end, or if the order of access is random, or if you´re accessing 1000000 times the same KB. – deviantfan Dec 04 '14 at 11:13

3 Answers3

7

On a typical modern CPU and OS, no, I wouldn't expect any difference in average access time, likelihood of cache miss, or (much worse) likelihood of page fault based on whether the buffer is in heap or stack. The only thing that should matter is your pattern of access to it, compared to other use of memory. However, there may be embedded or special-purpose platforms where the stack is kept in a different kind of memory than the heap.

You're ignoring a third possibility, non-heap memory (allocated by some OS-specific call, such as mmap, rather than malloc).

Finally, if you want to completely remove the possibility of page faults, the OS may provide a way to do that; for example, mlock on POSIX.

david
  • 997
  • 6
  • 15
  • You might want to add a bit about the different ways to access it, like as an offset from the stack-pointer, through a pointer, using a code-relative-address (PIC)... Those might have different impacts on register-pressure and access-overhead, and they might use different instructions (or instruction-sequences). – Deduplicator Dec 04 '14 at 11:15
  • Nice, thanks! I haven't heard of mmap, and haven't read much about page faults either, I'll look more into those. – DudeMan2000 Dec 04 '14 at 11:15
  • @Deduplicator This was a question about performance impact of choices in C, not assembler. I suppose an optimizing compiler might be able to use different instructions to access a buffer in a single function (or across a set of inline functions in the same source-file) if it's on the stack (a local variable) or static data (part of the program image, neither on the stack nor the heap). But that would distract further from the main point of the answer: in C, pointers point to RAM, not cache. – david Dec 21 '21 at 00:31
6

There is no difference in the access speed, its the same memory after all. Compiler never decide where buffer should be stored physically. It is hardware and operating system business.

Ari0nhh
  • 5,720
  • 3
  • 28
  • 33
  • Really? I thought the compiler would make optimizations where if you create a local variable and that variable is used a lot before it's freed, the compiler will assign that variable to a register. Does the compiler only make such calls on the use of registers, while all non-register memory is treated as "virtual memory" by the compiler, and managed by the OS and hardware? – DudeMan2000 Dec 04 '14 at 10:59
  • @DudeMan2000 Yes you are right, compiler could do that. But question is about buffer, not variable. Compiler could not deside: "Hmm. This is pretty important buffer lets put it to the processor L2 cache" – Ari0nhh Dec 04 '14 at 11:01
  • @DudeMan2000 Simplified: Pretty much everything has to be loaded from the RAM to a register when used in the processor, and then the changed value (if any) has to be moved back again. The processor has a limited amount of registers (not everything necessary will fit in it), but the loading and storing between RAM and Registers takes time. What the compiler can do is to to keep the most used variables for a piece of code in the register for some time without loading/unloading everytime it´s used. But that has nothing to do with the location in RAM. – deviantfan Dec 04 '14 at 11:05
  • And what the processor cache is in this scheme: A "intermediate" RAM. It´s not as big as the real RAM, but faster to load from (altough loading to the register is still necessary). – deviantfan Dec 04 '14 at 11:09
  • Also it is worth mentioning, that each register has very limited capacity - 16/32/64/etc bit, depending on your platform. You could store pointer to data in them, but not data itself. – Ari0nhh Dec 04 '14 at 11:09
  • Oh... OK I think I may have misunderstood the way cache works- so most variables will be stored on RAM, and then cache is used to temporarily create a copy of the memory in RAM for quicker access by the CPU; is that correct? So cache isn't like a section of RAM that's quicker to access; it's relationship to RAM is more analogous to RAMs relationship with the hard drive? – DudeMan2000 Dec 04 '14 at 11:23
  • Yes, thats basically it in essence. – Ari0nhh Dec 04 '14 at 11:30
2

No at all. heap ad stack are areas in the virtual address space that the operating system gives t your app. Their difference is what your app stores in the stack and what in the heap. All the reference types are stored in the heap and all the value types are stored in stack. Furthermore the lifetime of the things that are stored in the stack has the same duration as the lifetime of your app, while types stored in the heap may be garbage collected and the memory that they were using be reclaimed.

Christos
  • 53,228
  • 8
  • 76
  • 108