2013-03-24 81 views
6

使用新的C++ 11對齊工具我想確保一組臨時(堆棧)變量位於一個緩存行中。我第一次天真的嘗試如下:緩存對齊的堆棧變量

int main() { 
    alignas(64) int a; // 0x7fffc58aac80, properly aligned at 64 
    int b; // 0x7fffc58aac7c 
    int c; // 0x7fffc58aac78 
    return 0; 
} 

笨我!堆棧不以這種方式分配變量,因此a將位於不同的緩存行上,而不是bc

這是否意味着正確對齊多個變量的唯一方法是通過聚合

struct alignas(64) Abc { 
    int x; 
    int y; 
    int z; 
}; 

int main() { 
    Abc foo; 
    // x 0x7fff40c2d3c0 (aligned at 64) 
    // y 0x7fff40c2d3c4 
    // z 0x7fff40c2d3c8 
    return 0; 
} 

編譯:鏘3.2

+8

你真的認爲在同一個緩存行中擁有所有這些變量都會提高性能嗎?堆棧在緩存中的可能性相當不錯。 – 2013-03-24 01:13:33

+0

如果這些變量需要在多個內核之間共享,那麼無論哪個內核想要寫入這些內核,都需要一次使用全部三個變量。如果它們全都位於同一個緩存行中,並且訪問這些變量很少,則一致性流量將會減少。但是,不能保證在讀取同一行中的兩個變量之間該行可以失效。 – 2013-03-24 13:14:40

+1

現代編譯甚至不會將堆棧變量保存在固定位置(當然,除非您拿到地址)。因此,如果'a'和'b'共享一個緩存行,寫入任何一個可以改變的行後。 (這是典型的靜態單一分配優化) – MSalters 2013-03-24 18:56:52

回答

4

要準確對齊,您必須使用聚合幾個變量,因爲自動變量的佈局沒有定義。在C++ 11標準中我找不到任何東西,它說自動存儲的變量必須按照它們定義的順序在堆棧上分配。該標準的第5.9節堅持只定義了幾種指針比較,並且具有自動存儲的變量之間的比較不在所列出的定義範圍之內。