C ++ 11:新的返回连续内存吗?

时间:2016-02-08 15:55:49

标签: c++ c++11

float* tempBuf = new float[maxVoices]();

上述结果是否会

1)16字节对齐的内存?

2)确认连续的内存?

我想要的是以下内容:

float tempBuf[maxVoices] __attribute__ ((aligned));

但作为堆内存,这对Apple Accelerate框架有效。

感谢。

4 个答案:

答案 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)

  1. 保证在您分配的类型方面正确对齐。因此,如果它是一个4 float s的数组(每个假设为4个字节),则保证提供可用的float s序列。 保证与16个字节对齐。
  2. 是的,它保证是连续的(否则单个指针的含义是什么?)
  3. 如果您希望它与某些 K 字节对齐,您可以使用std::align手动执行此操作。有关更有效的方法,请参阅MSalter's答案。

答案 3 :(得分:0)

如果tempBuf不是nullptr,则C ++标准会保证tempBuf指向最少maxVoices个连续float s的第0个元素。

(一旦完成,请不要忘记致电delete[] tempBuf。)