2012-02-23 60 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