2012-02-23 40 views
2

上SSE2數據alignement的手工修復行動是否有一個替代以下手冊修復行動:替代一個16字節邊界

// excerpt adapted from SIMDTest in 
// http://www.mccauslandcenter.sc.edu/mricro/obsolete/graphics/simdtest.zip 
// 
var 
    lAdblRAp, lArraySz, lAdblRA, Doublep: LongInt; 
begin 
    // ... 
    GetMem(lAdblRAp,(lArraySz * SizeOf(Double)) + 32); 
    lAdblRA := Doublep((Integer(lAdblRAp) and $FFFFFFF0) + 16); 
    // ... 
end; 

注意,這一段代碼embbeded或者在過程或者在一個函數中。

回答

3

的標準方法是使用一個內存管理器,將調整16個字節邊界塊。 FastMM將執行此操作,但您需要完整版才能配置此選項。

還要注意的是,在你的問題的代碼是不是64位的準備,因爲它轉換一個指向4字節整數。

+0

重新標記我的帖子:我使用Windows 7/32位輸出 – menjaraz 2012-02-23 08:15:16

+0

總是值得寫的代碼,將在任何平臺上工作,在可能的情況。 NativeInt是Q. – 2012-02-23 08:21:12

+0

中的代碼應該使用的內容謝謝David。這很有趣,我正在等待Delphi XE2的繼任者轉向使用Linux作爲選項的64位。 – menjaraz 2012-02-23 08:30:00

2

如果您使用的是Delphi的新版本(我已經使用XE和XE2進行了測試),最好和最簡單的方法是首先在您的代碼中調用SetMinimumBlockAlignment(mba16Byte)

然後調用定期GetMemNew或任何內存分配功能,並確保該地址是對齊到16個字節邊界

編輯:

此外,如果你喜歡使用手動修復行動,浪費較少內存的最有效方式如下:

var 
    lArraySz: LongInt; 
    lAdblRAp, lAdblRA: Pointer;  

begin 
    // ... 
    GetMem(lAdblRAp,(lArraySz * SizeOf(Double)) + 16); 
    lAdblRA := Pointer((Integer(lAdblRAp) + 15) and $FFFFFFF0)); 
    // ... 
end; 

它將使用每個分配少於16個字節。

+0

+1。來自Embarcadero RAD Studio的報價有關* SetMinimumBlockAlignment *的幫助說明:'通過內存管理器分配的內存保證與至少8個字節的邊界對齊。當使用SSE指令操縱內存塊時,16字節對齊很有用,但可能會增加內存使用開銷。 – menjaraz 2012-02-23 10:56:42

+0

@menjaraz:如果您不需要16字節對齊了在你的代碼,你可以用'SetMinimumBlockAlignment(mba8Byte)'將其返回到8字節對齊。 它只會影響新分配的回憶。 – 2012-02-23 11:02:51

+0

@menjaraz:我還應該提到你也可能會在你的手動修復中浪費一些內存。但是,如果將塊對齊設置回8字節對齊,則內存管理器將在先前的16字節對齊的內存分配中重用可能的內存浪費。 – 2012-02-23 11:08:33