2014-02-19 33 views
1

我想強制一個特定的堆分配返回一個64字節對齊的地址,因爲這是一個緩存行邊界。我想我可以做這樣的如何使用alignof爲堆分配強制對齊?

int *p = new alignas(64) int; 

但沒有我的編譯器似乎給p這是64的倍數的地址,這裏是我如何檢查:

#include <iostream> 

int main() 
{ 
    int *p = new alignas(64) int; 
    std::cout << long(p) % 64 << '\n'; // should print 0 
} 

我必須做有問題。但是什麼?

+1

兩件事情:一)overaligned類型的支持是實現相關,和b )非常迂迴,你要檢查的是*轉換值*是否可分。就語言而言,除了通過新的對齊語言功能之外,您沒有「對齊指針」的概念。指針不是整數,只能轉換爲整數。 –

+0

請注意,我沒有檢查指針的對齊方式(這將是'&p'的值),我正在檢查它指向的對齊方式。是的,我同意,我正在檢查轉換爲「long」的指針的值,但有沒有更好的方法來查看我的對齊請求是否正在實現? – KnowItAllWannabe

+0

是的,新的語言功能非常豐富,可能有你需要的,例如, ['的std :: align'](http://en.cppreference.com/w/cpp/memory/align)。在C++ 11之前,簡單的*並不是*對齊內存的標準概念,這就是它被添加的原因。之前必須使用特定於平臺的方法。 –

回答

1

向64多個字節,比你需要的,然後生成分配的空間內的高速緩存對齊的地址。注意最後釋放整個分配的內存。

+0

我知道還有其他方法可以做我想做的事情(例如,使用'std :: aligned_storage'或'std :: align'),但是我真的很想明白爲什麼我使用'alignas' isn沒有工作。 – KnowItAllWannabe

+0

alignas運行在簡單的變量,而不是在新 –

+2

善良我無知 - 的std ::對齊的存儲看上去很漂亮性病::對齊不正是我建議,但更加整齊 –

2

由操作者new爲了分配空間稱爲(分配器是「假定返回指針存儲被適當地用於任何類型的基本 對準的對象對齊的」 § 3.7.4.1/2;引語來自§ 5.3.4/11)。 alignas(64)可能不是您的編譯器和環境的「基本對齊方式」,因此分配函數不需要考慮它。

注意分配功能僅通過了要求空間的大小;它不知道要求什麼路線。因此,它無法調整其結果以適應特殊需求。

alignas該類型說明符被設計爲靜態和自動對象一起工作。對於這樣的對象,如果它是基礎的,則必須遵守所請求的對齊,並且在理想的世界中,如果編譯器不能保證延伸的對齊將被遵守,則編譯器將產生錯誤消息。 (我不相信這是必須這樣做,雖然,GCC和鐺農產品可執行請求是一個巨大的堆棧對準該段錯誤。)

+0

我剛剛用g ++ 4測試過。8並沒有任何東西對齊超過8個字節(無論如何,這是標準的內存對齊)。因此我沒有看到該關鍵字的用處!在x86上,有些寄存器需要128字節對齊的內存(並且OP也使用64字節),但不知何故,這對於此目的完全沒有用處。太糟糕了。我甚至嘗試過一個結構和一個類,最後都沒有對齊。如果它只適用於已經正確對齊的類型,那麼就沒有必要添加到語言中! –

+0

@AlexisWilke:它專爲堆棧分配(自動)對象而設計。 (即使在那裏,它也不能保證工作,但是如果編譯器不能保證對齊,它會提供一個編譯時錯誤。)所有使用'new'分配的對象具有相同的對齊方式(至少使用默認分配函數)。我用gcc 4.8/linux試了一下,它和alignas(8192)一起工作的很好。 – rici

+0

嗯......有效。太糟糕了,它不會用新的做。我想我們仍然受到良好的舊memalign()函數的約束。 –