4

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
}
Ivan
  • 7,448
  • 14
  • 69
  • 134
  • possible duplicate of [Is double read atomic on an Intel architecture?](http://stackoverflow.com/questions/24731791/is-double-read-atomic-on-an-intel-architecture) – torvin Sep 10 '15 at 05:33
  • I am asking a specific question. How to tell the compiler to align a variable on an 8-byte boundary? – Ivan Sep 10 '15 at 12:21

2 Answers2

3

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks, it seems in this thread http://stackoverflow.com/questions/24731791/is-double-read-atomic-on-an-intel-architecture , unless I am reading it incorrectly, that one needs to build with x64 and not AnyCPU? "...So you'd need to build your assembly for x64 (not Any CPU). .." – Ivan Sep 10 '15 at 16:00
  • No, use AnyCPU. Which means what it says, if you run on a 64-bit OS then you get a 64-bit process. And it still works on a 32-bit OS. You only ever select x64 if you absolutely don't want your program to run on a 32-bit OS. – Hans Passant Sep 10 '15 at 16:13
0

All Windows heap allocations align on an 8-byte boundary already, and types are naturally-aligned. If you need to change this for some reason, Visual C# might support #pragma pack, but it doesn’t seem to be a documented option for MSVC ’15.

Davislor
  • 14,674
  • 2
  • 34
  • 49