2012-11-04 72 views
2

我使用英特爾的x86機器,和Windows 7,加的Visual C++(版本二千零十二分之二千零五快遞)數據的影響(MIS)對準

我一直在玩排列(我剛纔一直在做這個作爲一種學習練習)。當然,我理解在填充方面對類/結構大小的影響。我相信我明白,由於CPU指令工作和期望數據的方式,它也更好地對齊。

我已普遍在尋找許多不同的資源,例如(有趣) c++ data alignment /member order & inheritance (以及類似維基百科等環節),可以影響http://en.wikipedia.org/wiki/Data_structure_alignment

一個領域(我讀)似乎是性能,由於到需要數據爲寄存器的特定大小,未對齊的數據可能會導致問題(請參閱維基百科)。

我寫了一些代碼,我在其中創建了3個結構,所有成員的包裝設置爲1,常規對齊,並重新排列成員。這給了我的sizeof 8,10和12我跑了類似於以下每個代碼對象:

struct MixedData1 
{ 
    char Data1; 
    short Data2; 
    int Data3; 
    char Data4; 

    void operator() (MixedData1& md) 
    { 
     md.Data1 = 'a'; 
     md.Data2 = 1024; 
     md.Data3 = 1000000; 
     md.Data4 = 'b'; 
    } 
}; 

typedef std::vector<MixedData1> MDVector; 


int main(int argc, char* argv[]) 
{ 
    MixedData1 md; 
    for(int count = 0; count < 10 ; count++) 
    {  
     { 
     std::cout << sizeof(md) << std::endl; 
     boost::timer::auto_cpu_timer t; 
     MDVector mdv(10000000); 
     std::fill(mdv.begin(),mdv.end(),md); 
     std::for_each(mdv.begin(),mdv.end(),md); 
     } 
    } 
} 

我不是在價值觀真正感興趣所以在向量中每個元素被初始化相同。無論如何,我得到的結果表明,運行時間隨結構的大小增加 - I.E with pack(1)(8字節)我得到最快的0.08s,並且與正常對齊(12字節)我得到最慢的0.105。

我的問題是關於被錯誤對齊的影響。作爲一名C++程序員,我不認爲自己曾經在整個我的X年有任何問題,但當然它可能只是通過了我。 (1)在我的測試(編輯)中,對齊有一個效果(我相信),但是Neil表示它只是由於結構大小的差異所致。我試圖通過他的回覆來訪問該成員,但我在那裏看不到真正的效果......是否有更清晰的例子?有沒有辦法讓我看到錯位的戲劇性效果? (2)如果可能的話,是否有辦法引起錯位造成碰撞?

+0

在68000系列芯片(舊的Mac曾經擁有它們)未對齊的數據導致操作系統崩潰。這相當戲劇性。 – john

+0

@John我會挖掘我的舊atari ST:P – Caribou

回答

4

您的代碼所做的就是測試處理器複製內存的速度。內存越多,副本越慢。結構內各個成員的排列與副本的速度無關,只有結構的大小很重要。

如果您想查看對齊的效果,您需要編寫實際訪問單個未對齊結構成員的代碼。例如,您可以編寫一個循環來增加每個結構的data3成員。根據體系結構的不同,編譯器可能會意識到它必須使用不同的指令來執行算術;在x86上通常不是這樣,編譯器會發出自然的代碼,因爲處理器能夠處理未對齊的訪問。有些處理器實際上可以以與對齊的數據相同的速度讀取和寫入未對齊的數據。一個簡單的例子就是8088,因爲它只有一個8位數據總線,因此所有的16位指令都是用兩個負載仿真的,但最新的處理器大部分時間都是從緩存行讀取的,所以唯一的時間是未對齊的數據可能會有所不同的是數據何時穿過緩存線。

如果您想通過未對齊導致崩潰,那麼通常您需要在不同類型之間投射指針。然後,編譯器可能並不總是意識到您的指針可能未對齊,並且不會爲未對齊的訪問生成正確的指令。例如,您可以嘗試在cast char *指針上調用SSE指令。

+0

我有一種感覺,這是說實話,感謝信息,我會有進一步的發揮和更新。 – Caribou

+0

是的,我現在沒有看到明顯的區別,現在我正在訪問成員(Data3)... +1的幫助 - 謝謝 – Caribou

1

簡短的回答:在實踐中並不重要。

這裏的原因:1或2緩存缺失很可能會比一毫秒少,所以訪問未對齊數據將僅一個問題:

  1. 的數據跨越兩個高速緩存行
  2. 您訪問許多未對齊的數據片段在內存中不連續。

因爲2.無論如何都會產生大量的緩存未命中,即使數據對齊,也不應該出現這種情況。改進對齊可以將緩存未命中次數提高不超過2倍,但連續存儲數據可以多次提高性能。

有一些要求數據對齊的指令。如果你需要這些說明,你可以知道它或者你的編譯器應該確保你對齊。這是否會影響性能取決於處理器的微架構和編譯器。無論如何,您應該首先分析您的程序以找到瓶頸。如果對齊會顯着影響程序的性能,然後修復它。否則,不要擔心。

+0

非常感謝額外的信息 - 我認爲它是什麼的基本知識是什麼它比重視細節更重要。所以我同意你在這裏的答案。正如我所說,多年來我沒有遇到任何關於校準的問題,我猜想這可能是由於我使用的架構和編譯器,但我很高興現在瞭解這一點 - thx再次:) – Caribou