I have several classes that suffer from cache contention and are allocated with the "new" operator. Can I somehow make sure that "new" returns an address aligned to a cache line?
I am using GCC (if it's not portably possible).
I have several classes that suffer from cache contention and are allocated with the "new" operator. Can I somehow make sure that "new" returns an address aligned to a cache line?
I am using GCC (if it's not portably possible).
You can use memalign
or _aligned_alloc
for glibc or windows CRT systems respectively. you can even use a custom allocator like nedmalloc and have it align the blocks, which could also give you some other added bonuses.
you should also mark them with __attribute__((aligned(64)))
, just in case they get statically allocated.
The easiest way to solve this would be to make the objects big enough, that they can't share a cacheline. Using gcc you could set the alignment of the classes (I'm assuming your objects are smaller then a cacheline since you suffer from contention):
class foo {} __attribute__((aligned(2 * CL)));
You need to insert the correct Cachelinesize for your architecture for CL
of course (or put it into a macro an d use that there). I used twice the size of a cache line, because from what I remember new
doesn't guarantee that it will actually ensure the alignment is preserved. Since the object is therefore not guaranteed to start at the beginning of a cacheline you could still get parts of different objects in the same cacheline (that is the end of one object, and the start of another one). If the alignement is always preserved, __attribute__((aligned(CL)))
would be fine. Of course this will need you to change your structures and waste a lot of space.
You could also write your own new
(look here for how to do that) based on memalign
. For a more bandaid kind of solution you could also use memalign
directly and put an object inside the allocated space using placement new. Of course it makes the code using those objects less nice.
You can use placement new
to construct an object into a given region of memory:
// Instantiate object into a pre-allocated buffer
obj = new (buf) TheClass();
To get an aligned buffer buf
, you can use memalign
, sbrk
or mmap
.