float* tempBuf = new float[maxVoices]();
上述结果是否会
1)16字节对齐的内存?
2)确认连续的内存?
我想要的是以下内容:
float tempBuf[maxVoices] __attribute__ ((aligned));
但作为堆内存,这对Apple Accelerate框架有效。
感谢。
答案 0 :(得分:10)
内存将与float
对齐,但不一定是针对CPU特定的SIMD指令。我强烈怀疑你的系统sizeof(float) < 16
,这意味着它并不像你想要的那样对齐。内存将是连续的:&A[i] == &A[0] + i
。
如果您需要更具体的内容,new std::aligned_storage<Length, Alignment>
将返回一个合适的内存区域,当然假设您确实通过了更具体的对齐方式。
另一种选择是struct FourFloats alignas(16) {float[4] floats;};
- 这可能更自然地映射到框架。您现在需要new FourFloats[(maxVoices+3)/4]
。
答案 1 :(得分:6)
是的,new
会返回连续的内存。
至于对齐,没有提供这种对齐保证。试试这个:
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];
}
使用:
float* f = over_aligned<float,16>(37);
创建一个包含37个浮点数的数组,缓冲区对齐到16个字节。或者它无法编译。
如果断言失败,它仍然可以工作。测试并查阅编译器文档。一旦确信,将编译器特定的版本保护放在静态断言周围,所以当你改变编译器时,你可以重新测试(yay)。
如果您想要真正的可移植性,则必须回退到std::align
,并且与数据指针分开管理资源和计算T
的数量,当且仅当T
有一个非平凡的析构函数,然后在“缓冲区的开始”之前存储T
“的数量。它变得非常愚蠢。
答案 2 :(得分:2)
float
s的数组(每个假设为4个字节),则保证提供可用的float
s序列。 不保证与16个字节对齐。如果您希望它与某些 K 字节对齐,您可以使用std::align
手动执行此操作。有关更有效的方法,请参阅MSalter's答案。
答案 3 :(得分:0)
如果tempBuf
不是nullptr
,则C ++标准会保证tempBuf
指向最少maxVoices
个连续float
s的第0个元素。
(一旦完成,请不要忘记致电delete[] tempBuf
。)