2012-02-17 53 views
2

我目前正在嘗試構建一個代碼,該代碼適用於各種機器,從手持式口袋和傳感器到數據中心中的大型服務器。檢測目標CPU上對齊的內存要求

這些體系結構之間的(許多)差異之一是對齊內存訪問的要求。

「標準」x86 CPU上不需要對齊內存訪問,但許多其他CPU需要它,並且在不遵守規則時會產生異常。

到目前爲止,我一直在通過使用packed屬性(或pragma)強制編譯器對已知有風險的特定數據訪問進行謹慎處理。它工作正常。

問題是,編譯器非常謹慎,以至於在這個過程中大量的性能丟失了。因爲性能很重要,所以我們最好重寫代碼的某些部分以專門處理嚴格對齊的cpus。另一方面,這樣的代碼在支持未對齊內存訪問的cpus(比如x86)上會更慢,所以我們希望在需要嚴格對齊內存訪問的cpus上使用它只有

現在問題: 如何在編譯時檢測到目標架構需要嚴格對齊的內存訪問? (或其他方式)

回答

4

沒有C實現,我知道提供任何預處理器宏來幫助你弄清楚這一點。由於您的代碼應該運行在各種機器上,我假設您可以訪問各種機器進行測試,所以您可以通過測試程序找出答案。然後您可以編寫自己的宏,如下所示:

#if defined(__sparc__) 
/* Unaligned access will crash your app on a SPARC */ 
#define ALIGN_ACCESS 1 
#elif defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) 
/* Unaligned access is too slow on a PowerPC (maybe?) */ 
#define ALIGN_ACCESS 1 
#elif defined(__i386__) || defined(__x86_64__) || \ 
     defined(_M_IX86) || defined(_M_X64) 
/* x86/x64 are fairly forgiving */ 
#define ALIGN_ACCESS 0 
#else 
#warning "Unsupported architecture" 
#define ALIGN_ACCESS 1 
#endif 

請注意,未對齊訪問的速度將取決於其交叉的邊界。例如,如果訪問跨越4k頁面邊界,則訪問速度會更慢,並且可能存在其他邊界,導致其速度仍然較慢。即使在x86上,一些未對齊的訪問也不由處理器處理,而是由OS內核處理。那是非常慢。

也不保證未來(或當前)實現不會突然改變未對齊訪問的性能特徵。這已發生在過去和未來可能發生; PowerPC 601是非常寬容的未對齊訪問,但PowerPC 603e不是。

使事情變得更加複雜的事實是,爲編寫不對齊的訪問而編寫的代碼在不同平臺的實現中會有所不同。例如,在PowerPC上,通過x << 32x >> 32始終爲0,如果x爲32位,但在x86上沒有這樣的運氣,則可以簡化PowerPC。

+0

有趣。這確實是我開始這樣做的方式,但顯然,我不知道所有的架構在那裏......順便說一句,沒有不幸的是,我沒有「直接」訪問所有這些架構,所以我必須猜測提前解決大部分問題,以避免在代碼維護階段出現太多併發症。 – Cyan 2012-02-18 00:52:31

+0

您無法瞭解所有架構,但聲稱支持您無法訪問的架構是不負責任的,至少如果您正在編寫C語言。 – 2012-02-18 01:55:02

+0

我完全同意。我的目標主要是爲其他人定製軟件包,以便爲其自己的目標架構進行定製。準備得越好,下游越容易。但正如你所說,我不能「聲稱」完全驗證它。儘管如此,與「我不在乎」相比,優秀的軟件設計仍然具有優勢。 – Cyan 2012-02-20 10:03:09

4

無論如何,編寫嚴格內存對齊的代碼是一個好主意。即使在允許未對齊訪問的x86系統上,未對齊的讀/寫也會導致兩次內存訪問,並且某些性能將會丟失。編寫適用於所有CPU架構的高效代碼並不困難。要記住的簡單規則是指針必須與您正在閱讀或書寫的對象的大小對齊。例如如果寫入一個DWORD,則(dest_pointer & 3 == 0)。使用諸如「UNALIGNED_PTR」類型的柺杖會導致編譯器生成低效的代碼。如果你有大量必須立即工作的遺留代碼,那麼使用編譯器來「修復」這種情況是有道理的,但如果它是你的代碼,那麼從一開始就寫它來在所有系統上工作。

+0

不幸的是,有些情況下我沒有選擇,並且提供了一個指針,它可能*不能對齊。 – Cyan 2012-02-18 00:50:27

+0

您可以測試指針是否與此對齊: if((int)pointer&objectsize-1){take unaligned action} – BitBank 2012-02-18 00:52:27

+0

當然,但測試本身太慢了。每次更好地訪問一個字節的內存並從這些字節重建數據。很明顯,這個結論在支持未對齊訪問的CPU(如x86)上完全錯誤。 – Cyan 2012-02-18 00:59:03