代码之家  ›  专栏  ›  技术社区  ›  lppier

C++11:new是否返回连续内存?

  •  4
  • lppier  · 技术社区  · 10 年前
    float* tempBuf = new float[maxVoices]();
    

    上述结果是否会导致

    1) 16字节对齐的内存?

    2) 确认为连续的内存?

    我想要的是:

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

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

    谢谢

    4 回复  |  直到 10 年前
        1
  •  10
  •   MSalters    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] .

        2
  •  6
  •   Yakk - Adam Nevraumont    10 年前

    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个字节。或者它无法编译。

    如果断言失败,它仍然可以工作。测试并查阅编译器文档。一旦确信,就在静态断言周围设置编译器特定的版本保护,这样当您更改编译器时,就可以重新测试(是的)。

    如果你想要真正的可移植性,你必须有一个回退 std::align 并与数据指针分开管理资源 计算 T 当且仅当 T 有一个非平凡的析构函数,然后存储 T 在缓冲区开始之前。这变得相当愚蠢。

        3
  •  2
  •   Community Mohan Dere    9 年前
    1. 它保证与您分配的类型正确对齐。所以如果它是一个4 float s(每个假定为4字节),保证提供可用的序列 浮动 s、 它是 保证对齐到16字节。
    2. 是的,它保证是连续的(否则单个指针的含义是什么?)

    如果你想让它与一些 K 字节,您可以使用 std::align 看见 MSalter's 答案是一种更有效的方法。

        4
  •  0
  •   Bathsheba    10 年前

    如果 tempBuf 不是 nullptr 那么C++标准保证 临时Buf 指向最小的第零个元素 maxVoices 相接的 float s

    (别忘了打电话 delete[] tempBuf 一旦你做完了。)