Search code examples
c#thread-safetyalignmentatomic

c# align double on 8-byte boundary


This is not a duplicate question.

In a modern Intel CPU, a double on an 8-byte boundary built with x64 can be read/write without locking since it is guaranteed to be atomic. Is there a decorator, or how to do I tell the C# compiler to align on an 8-byte boundary.

What is the actual code for the [Align(8)] decorator below?

public class AClass
{
    [Align(8)]
    private static double d1;
    [Align(8)]
    private static double d2
    //and so on
}

Solution

  • You can place fields at arbitrary offsets with the [FieldOffset] attribute. Note the example in that MSDN article, [StructLayout(LayoutKind.Explicit)] required.

    But that doesn't help you at all, the alignment for double is already 8. You can't make it "better". What matters most of all is how the object itself is aligned. And that depends on the target platform.

    When you target x86, thus getting 32-bit machine code, the alignment you get from the GC heap and the stack is only 4. So you have 50% odds that the doubles are mis-aligned. You can only do better if the object is allocated in the Large Object Heap, it is aligned to 8. That requires storing the objects in an array that's at least 85,000 bytes. A special rule for double[] arrays, they get allocated in the LOH when they have at least 1000 elements.

    If you target x64 on a 64-bit OS, achieved by simply removing the jitter forcing in your project's Properties > Build tab and keeping AnyCPU, then objects are guaranteed to be aligned to 8. Which is what you should always aim for when manipulating a lot of doubles.