[英]Cache Line Alignment (Need clarification on article)
我最近在應用程序中遇到了我認為是錯誤共享的問題,我查閱了Sutter關於如何將數據與緩存行對齊的文章 。 他建議使用以下C ++代碼:
// C++ (using C++0x alignment syntax)
template<typename T>
struct cache_line_storage {
[[ align(CACHE_LINE_SIZE) ]] T data;
char pad[ CACHE_LINE_SIZE > sizeof(T)
? CACHE_LINE_SIZE - sizeof(T)
: 1 ];
};
當CACHE_LINE_SIZE > sizeof(T)
為true時,我可以看到這將如何工作 - struct cache_line_storage
最終會占用一個完整的內存緩存行。 但是,當sizeof(T)
大於單個緩存行時,我認為我們應該通過CACHE_LINE_SIZE - T % CACHE_LINE_SIZE
字節填充數據,以便生成的結構的大小是緩存行的整數倍尺寸。 我的理解有什么問題? 為什么填充1個字節就足夠了?
您不能擁有大小為0的數組,因此需要1才能進行編譯。 但是,該規范的當前草案版本說這種填充是不必要的; 編譯器必須填充結構的對齊方式。
另請注意,如果CACHE_LINE_SIZE
小於alignof(T)
,則此代碼CACHE_LINE_SIZE
alignof(T)
。 要解決此問題,您應該使用[[align(CACHE_LINE_SIZE), align(T)]]
,這將確保永遠不會選擇較小的對齊方式。
想像
#define CACHE_LINE_SIZE 32
sizeof(T) == 48
現在,考慮[[ align(CACHE_LINE_SIZE) ]]
工作原理。 例如:
[[ align(32) ]] Foo foo;
對於某些n
這將強制sizeof(Foo) == 32n
。 即如果必要的話,align()會為你填充,以便像Foo foo[10];
這樣的東西Foo foo[10];
使每個foo[i]
按要求對齊。
因此,在我們的例子中, sizeof(T) == 48
,這意味着sizeof(cache_line_storage<T>) == 64
。
因此,對齊為您提供了您希望的填充。
但是,這是模板中的一個“錯誤”。 考慮這種情況:
#define CACHE_LINE_SIZE 32
sizeof(T) == 32
在這里,我們最終得到了char pad[1];
。 這意味着sizeof(cache_line_storage<T>) == 64
。 可能不是你想要的!
我認為模板需要稍微修改一下:
template <typename T, int padding>
struct pad_or_not
{
T data;
char pad[padding];
};
// specialize the 0 case
// As it is late, I am SURE I've got the specialization syntax wrong...
template <typename T, int>
struct pad_or_not<0>
{
T data;
};
template<typename T>
struct cache_line_storage {
[[ align(CACHE_LINE_SIZE) ]] pad_or_not<T, (sizeof(T) > CACHE_LINE_SIZE ? 0 : CACHE_LINE_SIZE - sizeof(T) ) > data;
};
或類似的東西。
“你不能擁有大小為0的數組,因此需要1才能使其編譯” - GNU C允許將數組標注為零。 另見http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Zero-Length.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.