Reputation: 1987
float* tempBuf = new float[maxVoices]();
Will the above result in
1) memory that is 16-byte aligned?
2) memory that is confirmed to be contiguous?
What I want is the following:
float tempBuf[maxVoices] __attribute__ ((aligned));
but as heap memory, that will be effective for Apple Accelerate framework.
Thanks.
Upvotes: 4
Views: 592
Reputation: 179981
The memory will be aligned for float
, but not necessarily for CPU-specific SIMD instructions. I strongly suspect on your system sizeof(float) < 16
, though, which means it's not as aligned as you want. The memory will be contiguous: &A[i] == &A[0] + i
.
If you need something more specific, new std::aligned_storage<Length, Alignment>
will return a suitable region of memory, presuming of course that you did in fact pass a more specific alignment.
Another alternative is struct FourFloats alignas(16) {float[4] floats;};
- this may map more naturally to the framework. You'd now need to do new FourFloats[(maxVoices+3)/4]
.
Upvotes: 10
Reputation: 275740
Yes, new
returns contiguous memory.
As for alignment, no such alignment guarantee is provided. Try this:
template<class T, size_t A>
T* over_aligned(size_t N){
static_assert(A <= alignof(std::max_align_t),
"Over-alignment is implementation-defined."
);
static_assert( std::is_trivially_destructible<T>{},
"Function does not store number of elements to destroy"
);
using Helper=std::aligned_storage_t<sizeof(T), A>;
auto* ptr = new Helper[(N+sizeof(Helper)-1)/sizeof(Helper)];
return new(ptr) T[N];
}
Use:
float* f = over_aligned<float,16>(37);
Makes an array of 37 floats, with the buffer aligned to 16 bytes. Or it fails to compile.
If the assert fails, it can still work. Test and consult your compiler documentation. Once convinced, put compiler-specific version guards around the static assert, so when you change compilers you can test all over again (yay).
If you want real portability, you have to have a fall back to std::align
and manage resources separately from data pointers and count the number of T
if and only if T
has a non-trivial destructor, then store the number of T
"before" the start of your buffer. It gets pretty silly.
Upvotes: 6
Reputation: 8141
float
s (each supposedly 4 bytes), it's guaranteed to provide a usable sequence of float
s. It's not guaranteed to be aligned to 16 bytes.If you want it to be aligned to some K bytes, you can do it manually with std::align
. See MSalter's answer for a more efficient way of doing this.
Upvotes: 2
Reputation: 234785
If tempBuf
is not nullptr
then the C++ standard guarantees that tempBuf
points to the zeroth element of least maxVoices
contiguous float
s.
(Don't forget to call delete[] tempBuf
once you're done with it.)
Upvotes: 0