views:

2073

answers:

7

What is the C++ memory model for concurrency as defined by current standard?

What about upcoming C++0x standard? Will it change the memory model to support concurrency better?

+2  A: 

Unfortunately in C++ there is no "Standard Memory Model" like that of Java. The actual implementation is left up to the compiler, runtime libraries and processors.

Thus the C++ memory model == chaotic mix-mash of models, which means you always have to try to write safe code that doesn't depend on a specific memory model, and that goes for threaded programming as well, because the compiler can do any optimization it wants to outside of a critical section, even out of order processing!

Robert Gould
You say that like it's a bad thing
1800 INFORMATION
Paul Nathan
@Vlion: you're mistaken. The memory model is a description of when and why physical memory get read/written. Hardware is mostly irrelevant here except that what will be specified must be implementable on current hardware !
bltxd
Thanks blue.tuxedo for covering me there ;) Should have been more specific on my answer for those that aren't familiar with the term itself.
Robert Gould
+1  A: 

Short answer: there is none

Long answer: C++ does not have managed memory, you have to allocate it and free it yourself. Smart pointer classes can make this less burdensome. If you forget to free memory that you allocated, that's a memory leak and a bug. If you try to use memory after freeing it, or you try to free memory more than once, those are also nasty bugs.

As for the low-level details, C++ does not specify that - it's up to the hardware. Memory is accessed through pointers, which contain some sort of memory address. Memory addresses can either be physical addresses or virtual addresses. You'll only see physical addresses if you're working on an operating system kernel, or if you're reading old DOS code that ran in real mode. For more details, read up virtual memory, there's lots of good resources out there.

The x86 architecture also allows memory to be addressed using segment descriptors. This is a whole nother can of worms, which hasn't really been used since the days of Win16, and if you're lucky, you'll never have to deal with it.

Adam Rosenfield
A: 

In a nutshell, the C++ memory model consists of...

  • A stack that grows downward -- that is, when you push a stack frame the stack pointer has a value less that it was

  • A heap that grows upward, that is the end address of the newly allocated memory is greater it was before the memory. You allocate memory in the heap using malloc() or new. If there is not enough memory available in the heap then malloc (or new) calls the system function brk() sbrk() to increase the size of the heap. If the call to brk() or sbrk() fails then malloc or new fails with an out of memory exception.

You should never need to care whether the stack or heap grow down or up and in some systems these may operate the other way around. Just consider that the stack and heap grow inwards from the ends of the address space.

  • A memory allocator, malloc, which allocates memory in terms of 8-bit bytes. New also allocates memory, but the amount of memory that it allocates is based on the size of the object being newed.

  • Text space which contains the executable code. Text resides below the heap. You cannot alter the text space during execution

A program may have other special purpose sections below text.

You can see how a program is organized statically (before it's loaded) using objdump on linux systems.

I noticed that although you didn't mention it in your question, "concurrency" is one of the keywords you assigned to this question. Threading systems allcoate additional thread space on the heap for each thread and then manage the stack pointer to switch between threads.

There are a lot more details, many of which are specific to particluar hardware, OSes, or threading system, but that's the essential idea.

mxg
The direction of stack growth is dependent on hardware architecture, not any C++ memory model.
Ferruccio
You are correct. Possibly I didn't write that clearly, but that's what I said.
mxg
+20  A: 
bltxd
I think you're a little harsh here. C++/C are the languages of choice for most real-time, mission-critical, multi-threaded embedded systems. While the C++ standard has no MT support, no C++ compiler vendor will get far selling a tool which cannot be used in an MT environment.
Roddy
You're right, I reread myself and this sounds harsh. However I suggest you read this if you haven't:http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2007/n2197.pdfAll C/C++ toolchains are affected by this issue.
bltxd
The double-checked pattern is perfectly fine according to C. Theory doesn't match practice, unfortunately, as real processors do reorder.
MSalters
Pointers ? C has no notion of threads, are you talking about single threaded behavior ?
bltxd
Sorry, but an assertion like "the double-checked pattern is fine according to C" is nonsense, for the reasons given in the post. With the memory model under development, I don't think it's fine either by default, but there should be a way to make the compiler produce the needed barriers (through so-called 'low-level atomics', IIRC).
Blaisorblade
Nonsense? The standard describes an ideal world in which it works - no reordering exists in that world, and things happen sequentially. It then acknowledges that specific non-observable transformations are allowed, and describes what (non-)observable means - a concession to reality. The amount of reordering needed to break DCLP is observable, and thus disallowed.
MSalters
It's true: "C++0x" and C1x will be the first C++ and C standards to say anything whatsoever about what happens when you use threads. Without this, really bad things do happen: see the blog entry http://www.thegibson.org/blog/archives/23 "Memory ordering and memory models" (and the linked LKML and GCC list threads) for an example of what can happen when there are no rules to tell the compiler implementors what they can and cannot do. So, sure, many things seem to work now, but that's mostly luck...
SamB
+1  A: 

What about checking the papers on the C++ standard committee website:

?

Luc Hermitte
+15  A: 

Seeing some other answers, it seems many C++ programmers are not even aware what the "memory model" you are asking about means.

The questions is about memory model in the sense: what guarantees (if any) are there about write / read reordering (which may happen on the compiler side or on the runtime side)? This question is very important for multithreaded programming, as without such rules writing correct multithread programs is not possible, and somewhat surprising truth is with current lack of explicit memory model many multithreaded programs work more or less "by sheer luck" - most often thanks to compilers assuming pointer aliasing across function calls. - see Threads Cannot be Implemented as a Library

In current C++ there is no standard memory model. Some compilers define memory model for volatile variables, but this is nonstandard. C++0x defines new "atomic" primitives for this purpose. Exhaustive starting point to check what recent status is can be found at Threads and memory model for C++

Important links are also Concurrency memory model, Atomic Types and C++ Data-Dependency Ordering: Atomics and Memory Model standard proposals.

Suma
+1  A: 

If you'd like to get a deeper understanding of shared memory consistency models, I'd refer you to the following tutorial.

http://rsim.cs.uiuc.edu/~sadve/Publications/computer96.pdf

reprogrammer