Reputation: 3290
I have a 64 bit machine running a 64 bit processor but my application is 32 bit. Is reading or writing to a double guaranteed to be atomic? I am talking about assignment and reading only. How does a 32 bit process affect this process? Can the reader ever read partial value from a double when other thread is writing to it in given specs?
Upvotes: 2
Views: 300
Reputation: 941457
No. A double can easily straddle the L1 cache line boundary, requiring multiple bus cycles to glue the two pieces together. A very real problem in C#, the 32-bit CLR only provides an alignment guarantee of 4.
These misaligned accesses are not only not atomic, they are also expensive due to the shuffling the processor needs to do. Code that uses double can have 3 distinct timings, fast if the double happens to be aligned to 8 by accident, twice as slow when it is misaligned to 4 but still inside an L1 cache line, over three times slower when it is misaligned across a cache line. Such a program can randomly bump into one of these modes when the garbage collector compacts the heap and moves the double. Be very wary of this, a synthetic test program can easily miss this failure mode.
The perf problem is the core reason that a double[] is allocated in the Large Object Heap much sooner normal. The LOH provides an alignment to 8 guarantee. The normal rule is for objects >= 85,000 bytes, for double[] in 32-bit mode it is 8,000 bytes (1000 elements in the array).
You must use Interlocked.Exchange() if you need the atomicity guarantee. And I ought to post the disclaimer that atomicity is a very weak guarantee and no substitute for proper locking when requried.
Upvotes: 4