簡體   English   中英

為多個緩沖區分配內存,包括對齊

[英]Allocating memory for multiple buffers including alignment

我想為幾種不同類型的連續數組分配內存。 也就是說,像這樣,但具有動態大小:

template <typename T0, std::size_t N0, typename T1, std::size_t N1, ...>
struct {
    T0 t0s[N0];
    T1 t1s[N1];
    ...
};

天真地,大小只是sizeof(T0) * N0 + sizeof(T1) * N1 + ...但我認為對齊使它變得棘手。 您將在alignof(T0)上對齊整個內容,然后在N0 T0 s 之后,您必須找出alignof(T1)點以開始T1 s。 為此有std::align ,但它旨在在您已經分配內存后找到將它們放在哪里,因此在分配內存之前使用它需要一些努力。

是否有一些簡單的現成方法來計算這樣的動態結構的大小和偏移量? 我正在想象一個像

// Return the offsets in bytes of the ends of each array
template <typename... Ts>
std::array<std::size_t, sizeof...(Ts)> 
calculateOffsets(const std::array<std::size_t, sizeof...(Ts)> sizes);

例如:

auto offsets = calculateOffets<char, float>({3, 2});
// Offsets is now {4, 12} because the layout is [cccXffffFFFF] where c is a char, X is padding, f and F are the two floats.
// Now we can allocate a buffer of size offsets.back() with alignment alignof(char) and placement-new 3 chars starting at buf + 0, and 2 floats at buf + offsets.front()

這很有趣,因為編譯器顯然內置了這個邏輯,因為在編譯時,當大小是靜態的時,它知道上述結構的布局。

(到目前為止,我只對 POD 類型感興趣;要完全通用,我還需要處理異常安全的構造和銷毀。)

是否有一些簡單的現成方法來計算這樣的動態結構的大小和偏移量?

標准庫中沒有這樣的函數。 您可以在循環中使用std::align來實現它。

對此沒有內置工具——但這在 C++ 中是一個可解決的問題。

由於您正在有效尋找的是對齊的連續組件的“打包緩沖區”,因此我建議通過在最對齊的 object的對齊位置分配所有緩沖區的總和來做到這一點。 這使得以字節為單位的緩沖區長度的計算變得容易——但需要重新映射數據的順序。

對齊時要記住的是,16 字節邊界也與 8 字節邊界對齊(依此類推)。 另一方面,來自 1 字節邊界的 4 個字節將位於 4 字節邊界1上是不正確的。 可能是,但這取決於初始指針。

例子

例如,我們希望緩沖區中有以下內容:

  • 3 個char ( c )
  • 2 float ( f )
  • 2 short s ( s )

我們假設以下情況為真:

  • alignof(float) >= alignof(short) >= alignof(char)
  • sizeof(float)4
  • sizeof(short)2
  • sizeof(char)1

根據我們的需要,我們需要一個sizeof(float) * 2 + sizeof(short) * 2 + sizeof(char) * 3 = 15字節的緩沖區。

已按對齊方式排序的緩沖區在打包時如下所示:

ffff ffff ssss ccc

只要初始分配與alignof(float)對齊,此緩沖區中的其余字節也可以保證適當對齊。

如果您可以將數據始終按對齊的降序排列,那將是理想的; 但是,如果不能保證確實如此,您始終可以使用預制模板元編程解決方案根據每個對象的alignof(T)T...類型列表進行排序。


1您建議按緩沖區順序對齊的問題是,像alignof(char)這樣的情況,它是1個字節,並不能保證3 char之后和初始對齊中的1填充字節對齊到4個字節結盟。 0x00FFFFFE01的指針是“1 字節對齊”,但 4 個字節之后是0x00FFFFFE05它仍然是未對齊的。

盡管這可能適用於某些底層分配器,例如new / std::malloc ,它們具有alignof(std::max_align_t)的默認對齊方式 - 對於更精確的分配機制(例如在std::polymorphic_allocator找到的分配機制alignof(std::max_align_t) ,情況並非如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM