Skip to content

Latest commit

 

History

History
38 lines (21 loc) · 1.89 KB

README.md

File metadata and controls

38 lines (21 loc) · 1.89 KB

Aligned

Memory alignment wrappers, useful for avoiding false sharing

Usage

Aligned<T, 64> gives you access to a stack allocated, initialized instance of T, which is aligned to a 64-byte boundary in memory (a memory address which is a multiple of 64), and padded out at least to the next 64-byte boundary. This effetively gives you a container to hold an object which you need to be on a boundary.

This is useful if you need to avoid false sharing in a concurrent system. For example, if your cache line size is 64 bytes, like most modern processors...

Aligned<std::atomic<int>, 64> alignedCount = 0;

...will provide you with easy access to an std::atomic<int> instance which won't be subject to false sharing, since alignedCount.Ref() returns a reference to a std::atomic<int> instance which lies alone in memory which is aligned and sized correctly to fit in the 64-byte cache line.

You can use the std::atomic<int> as you'd expect with ++count.Ref();, for example.

Ts with Alignment unknown at compile time (are allocated on the heap, of course, and) are supported with

Aligned<T> alignedFoo(cacheLineSize);

Stack allocated arrays are supported with

Aligned<Foo[12], 64> alignedFoos;
alignedFoos[0] = Foo();

Heap allocated arrays with Alignment unknown at compile time are supported with

Aligned<Foo[12]> alignedFoos(cacheLineSize);

Heap allocated arrays with size and alignment unkown at compile time are supported with

Aligned<Foo[]> alignedFoos(12, cacheLineSize);

If you don't know the target machine's cache line size and don't want to guess that it's the usual 64 bytes, You can use the two CacheAligned classes provided...

CacheAligned<Foo[]> cacheAlignedFoos(12); // Grabs the cache line size at run-time. This works on Windows, Mac OS X, and Linux
CacheAligned<Foo> cacheAlignedFoo; // initialized using Foo() and the cache line size at run-time