Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::make_unique<T[]> required to return aligned memory?

Tags:

c++

arrays

c++14

  • Is the memory owned by the unique pointer array_ptr:

    auto array_ptr = std::make_unique<double[]>(size);
    

    aligned to a sizeof(double) alignof(double) boundary (i.e. is it required by the std to be correctly aligned)?

  • Is the first element of the array the first element of a cache line?

  • Otherwise: what is the correct way of achieving this in C++14?

Motivation (update): I plan to use SIMD instructions on the array and since cache lines are the basic unit of memory on every single architecture that I know of I'd rather just allocate memory correctly such that the first element of the array is at the beginning of a cache line. Note that SIMD instructions work as long as the elements are correctly aligned (independently of the position of the elements between cache lines). However, I don't know if that has an influence at all but I can guess that yes, it does. Furthermore, I want to use these SIMD instructions on my raw memory inside a kernel. It is an optimization detail of a kernel so I don't want to allocate e.g. __int128 instead of int.

like image 700
gnzlbg Avatar asked May 19 '14 08:05

gnzlbg


1 Answers

  • All objects that you obtain "normally" are suitably aligned, i.e. aligned at alignof(T) (which need not be the same as sizeof(T). That includes dynamic arrays. (Typically, the allocator ::operator new will just return a maximally aligned address so as not to have to worry about how the memory is used.)

  • There are no cache lines in C++. This is a platform specific issue that you need to deal with yourself (but alignas may help).

  • Try alignas plus a static check if it works (since support for over-aligned types is platform dependent), otherwise just add manual padding. You don't really care whether your data is at the beginning of a cache line, only that no two data elements are on the same cache line.

It is worth stressing that alignment isn't actually a concept you can check directly in C++, since pointers are not numbers. They are convertible to numbers, but the conversion is not generally meaningful other than being reversible. You need something like std::align to actually say "I have aligned memory", or just use alignas on your types directly.

like image 77
Kerrek SB Avatar answered Oct 12 '22 20:10

Kerrek SB