Re: Named shared memory without synchronization
- From: "Alex Blekhman" <xfkt@xxxxxxxxx>
- Date: Thu, 23 Nov 2006 23:24:44 +0200
"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
.
- Follow-Ups:
- Re: Named shared memory without synchronization
- From: adebaene
- Re: Named shared memory without synchronization
- Prev by Date: Re: "try = _try"
- Next by Date: Re: Named shared memory without synchronization
- Previous by thread: Problem with unmanaged pointer in managed c++
- Next by thread: Re: Named shared memory without synchronization
- Index(es):
Relevant Pages
|