2016-02-12 26 views
6

我想overalign緩存邊界上我喜歡的類型,所以我用alignasalignas用關鍵字not尊重

struct alignas(64) W { }; 

編譯沒有問題。不過,出乎我的意料,當我嘗試分配一堆W S,他們不是64字節對齊的,但實際上16字節對齊:

#include <iostream> 
#include <iomanip> 
#include <unordered_map> 

struct alignas(64) W { }; 

int main() { 
    std::unordered_map<int, int> offset; 

    for (int i = 0; i < 1000; ++i) { 
     auto w = new W; 
     offset[(uintptr_t)w % 64]++; 
    } 

    for (const auto& p : offset) { 
     std::cout << p.first << ' ' << p.second << '\n'; 
    } 
} 

產量:

0 250 
16 250 
32 250 
48 250 

上幾個編譯(gcc 4.8.2,gcc 5.2.0,clang 3.7.1)。這是怎麼回事?我告訴它調整,爲什麼不調整?

+5

[「這是執行定義是否支持過度對齊類型(\ [basic.align \])。」](http://eel.is/c++draft/expr.new#1)。另見[CWG issue 2130](http://wg21.link/cwg2130)。 –

+1

@ T.C。這看起來應該是一個答案。 – NathanOliver

+0

@ T.C。我怎麼知道一個實現是否支持它(顯然gcc和clang都沒有) – Barry

回答

3

這是很好的在這裏找到答案:https://stackoverflow.com/a/16510895

基本上是:new(至少在其正常使用),不僅保證每次調用new恆定的最大對齊(alignof(std::max_align_t))。

2

另一個答案是正確的,它解釋了現有的限制,但我想指出事情會變得更好。

正如T.C.在評論中,這是該語言長期存在的缺陷。它looksthe WG effort解決這個問題已導致在C++ 17(剛剛獲得功能完整狀態)的解決方案。因此,在編譯到該標準時,通過使用新的std::align_val_t重載new,動態分配將最終考慮全局排列。從而解決巴里的問題!

鑑於新型腳手架所需要的量,我想這不會回遷到較早版本的標準,所以老告誡他們的動態分配僅sufficing具有基本的定位大概會保持真實的類型。