Re: Named shared memory without synchronization



"Dan Schwartz" wrote:
I have the following scenario:
A primitive (integer) lives in a shared memory page.
Process 1: reads it every once in a while
Process 2: writes to to it fairly often

Since this is an int, my assumption was that this scenario would not benefit
from synchronization, as an int in the C language is defined (if I'm not
mistaken) as the
width of the CPU register, thus being atomic and uncorruptable.

This is correct. Actually, there is no strict requirement in C language that `int' should be equal to CPU register. Here's the quote from the C Standard:

<quote>
6.2.5 Types

5 [...] A "plain" int object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the range INT_MIN to INT_MAX as defined in the header <limits.h>).
</quote>

So, theoretically `int' can be larger that CPU register. However, I didn't encounter yet any 32-bit implementation where `int' isn't equal to CPU register. Probably in a world of embedded devices there are some.

Several articles I've seen on the net however, maintained that I need to
declare the primitive as volatile (which makes sense to me) and aligned to a
word boundry (which doesn't make sense to me).

As you already figured out `volatile' specifier is required in order to tell the compiler that it should not assume any optimizations regarding a variable. Alignment is important because unaligned variable may require more than one instruction to access it, therefore breaching atimicity of an access. Here's good article about alignment:

"Windows Data Alignment on IPF, x86, and x64"
http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vcconWindowsDataAlignmentOnIPFX86X86-64.asp

Accessing unaligned data is discussed in section "Why Is Alignment a Concern?".

After implementing the above scenario, it became apparent that the compiler
doesn't need the volatile declaration. The integer seems to be fetched again
for every access. In general, after substantial testing, I haven't found
drawbacks to this no-lock strategy. This, of course, means nothing. Nothing
can ever be validated with testing when dealing with synchronization issues.

My question(s):

Is this really a stable solution?

No. I'd suggest to use `volatile' specifier, so compiler will be aware of possibility of asynchronous changes. In your specific case optimizer didn't kick in for whatever reason, but I wouldn't rely on that in the future.

Does the compiler know that the integer lives in a shared page and becomes
'implicitly' volatile?

No, compiler doesn't have any chance to know about that. That's why `volatile' specifier was invented in first place.

If not, does this mean that the same startegy would work for thread
synchronization of an integral global variable?

Integral global variable can be used for thread synchronization without a problem. Such solution may seem dirty, since there is plenty of synchronization facilities in Windows system. Nevertheless, it can be done with global `int', too.

What about alignment, what would be the reason to worry about it for
primitive types?

The reason is that unaligned primitive types can become not so primitive and access to them will require several instructions. It explained well in above mentioned article.

HTH
Alex

.



Relevant Pages

  • Re: Thread question
    ... the variables freely, without synchronization. ... I merely said your advice was incorrect. ... use volatile -- doing so unnecessarily slows down your programs, ... VOLATILE int total=0; ...
    (comp.os.linux.development.apps)
  • [git patches] net driver updates #2
    ... struct sk_buff *skb, int ring_offset) ... +static int use_mcs; ... volatile u8 RCR; ...
    (Linux-Kernel)
  • Re: Is the following code MT-Safe?
    ... the assert (which is a fundamental design error: ... and almost always leads to either major synchronization failures ... >Does _bRunning need to be tagged as volatile? ... compiler to cache values, but only during the execution of a function; ...
    (microsoft.public.vc.mfc)
  • Re: Two more multithreading questions
    ... I want to know if making the variable volatile will guarantee that the second thread always sees the latest integer created by the first thread. ... is that when one thread executes assignment statements to volatile ... It is possible that one thread starts executing an assignment statement ... JLS 17.4.4 Synchronization Order ...
    (comp.lang.java.programmer)
  • Re: Share .cpp and .h along projects
    ... pvector = InterlockedExchangePointerAcquire(&g_sharedVector, ... I really would like to hear what you think volatile accomplishes ... You can't require people to use volatile on top of synchronization. ... compiler useful for multithreaded programming. ...
    (microsoft.public.vc.language)