[英]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上是不正確的。 它可能是,但這取決於初始指針。
例如,我們希望緩沖區中有以下內容:
char
( c
)float
( f
)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.