Skip to content

Commit

Permalink
Updated README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
NickStrupat committed May 11, 2014
1 parent f9cffd6 commit 1100aab
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 7 deletions.
8 changes: 4 additions & 4 deletions Aligned.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class Aligned : AlignedBase<T, Alignment> {
: pValue(ALIGNED_POINTER(T, bytes, SizeOfTPaddedToAlignment))
{ *pValue = T(value); }
~Aligned() { pValue->~T(); }
T & Get() { return *pValue; }
T const & Get() const { return *pValue; }
T & Ref() { return *pValue; }
T const & Ref() const { return *pValue; }
};

template<typename T>
Expand All @@ -35,8 +35,8 @@ class Aligned<T, -1> : AlignedBase<T, -1> {
pValue(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
{ *pValue = T(value); }
~Aligned() { pValue->~T(); }
T & Get() { return *pValue; }
T const & Get() const { return *pValue; }
T & Ref() { return *pValue; }
T const & Ref() const { return *pValue; }
};

template<typename T, std::size_t Size, std::size_t Alignment>
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ Memory alignment wrappers, useful for avoiding false sharing

## Usage

Aligned<T, 64> gives you access to a stack allocated, uninitialized 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.
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.reference()` 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.
...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.reference();`, for example.
You can use the `std::atomic<int>` as you'd expect with `++count.Ref();`, for example.

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

Expand All @@ -31,3 +31,8 @@ Heap allocated arrays with `Alignment` unknown at compile time are supported wit
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<T> 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

0 comments on commit 1100aab

Please sign in to comment.