2013-11-28 47 views
1

我想弄清楚是否有可能会出现这样的情况,如果试图节省内存使用“打包阵列[类型]”可能是有利的。德尔福64位内部数据格式/动态数组

您可以阅读在Win32位,但情况并非如此: http://docwiki.embarcadero.com/RADStudio/XE4/en/Internal_Data_Formats#Dynamic_Array_Types

一般来说,它似乎对我来说运行时代码动态数组将fasterif从未使用项目之间的填充是。但是因为我相信Delphi/64bit中的默认对齐方式是8byte,所以看起来您有一天可能无法依靠包含例如Delphi /布尔值默认为“打包”

+1

不,我能想到的使用'上的任何阵列或记录类型packed'唯一用途是用于读取存储在一个磁盘文件的数据,或偶尔与WinAPI的相互作用向后兼容性。这样做对于现代CPU架构和RAM可用性来说是绝对没有内存优势的,并且它实际上可以降低代码的性能,因为它使用的不是本地对齐方式。 –

+1

包装较慢 –

+0

我找不到它在您链接的文件中说明的地方。 –

回答

1

首先,我认为您需要小心如何阅读文档。它没有一直更新,并且某些部分显示为特定于Win32的事实决不能用于推断Win64的不同之处。事实上,对于您提出的问题,32位和64位之间没有实质性差异。

对于Delphi,使用打包在数组上不会改变连续元素之间的填充。数组中两个相邻元素之间的距离等于SizeOf(T),其中T是元素类型。无论使用包装修饰符如何,这都是正确的。使用打包在数组上甚至不会影响数组的对齐。

因此,要完全清楚明确,packed在阵列上使用时完全没有影响。编译器以与处理非压缩数组完全相同的方式处理压缩数组。

此声明似乎与文档不符。该documentation状态:

结构类型

默认情况下的对齐,结构类型的值在字处理或 双字边界以便更快地访问对齐。

但是,您可以通过在声明结构化类型时包含保留的 字来指定字节对齐。打包字 指定压缩数据存储。下面是一个例子声明:

type TNumbers = packed array [1..100] of Real; 

但是考虑此程序:

{$APPTYPE CONSOLE} 

type 
    TNumbers = packed array [1..100] of Real; 

type 
    TRec = record 
    a: Byte; 
    b: TNumbers; 
    end; 

begin 
    Writeln(Integer(@TRec(nil^).a)); 
    Writeln(Integer(@TRec(nil^).b)); 
    Readln; 
end. 

它的输出,采用Delphi XE2是:

 
0 
8 

因此,使用packed与与文档相反,数组不会修改类型的对齐方式。

注意上面的程序,当由德尔福6编制,具有输出

 
0 
1 

所以这样看来,编译器已经改变,但是文件并没有赶上。

可以在这里找到一个相关的问题:Are there any difference between array and packed array in Delphi?但是请注意,Barry Kelly(Embarcadero编译器工程师在编写答案时)的答案没有提到编译器行为的变化。


一般来说,这似乎给我,如果从来没有使用项目之间填充运行时代码会更快。

如上所述,对于数组,数组元素之间永远不会有填充。

我相信德尔福/ 64位默认对齐是8字节。

比对由数据类型决定,与目标架构无关。所以一个布尔值的对齐值为1.一个字的对齐值为2.一个整数值的对齐值为4.一个Double值的对齐值为8.这些对齐值在32位和64位上是相同的。

对齐对性能有巨大的影响。如果你关心性能,你应该根据一般原则不要打包数据结构。如果您希望最小化结构(类或记录)的大小,请首先放置较大的元素以最小化填充。这可以提高性能,但也可能使其恶化。

但是没有一条硬性规定。我可以想象,如果包装的东西几乎没有被访问过,包装可以提高性能。事实上,我可以更容易想象,改变结构中元素的顺序以将其组合起来可以提高性能。

+0

“...改变结构中元素的顺序来分组相关元素可以提高性能。” ...或者有时会降低性能,例如在对这些元素的多线程访问中。 – iamjoosy

+0

@iam虚假分享。确实。我正在将数据私有化为一个线程。通过相关数据,我的意思是一起操作的数据。通常发生在同一个线程上。通常,虚假分享往往是数组和来自不同线程的相邻元素的访问问题。你选择的那句话是考虑记录和类而不是数组。底线是没有一条单独的规则可以遵循。 –

+0

事实上,没有单一的规则可以遵循,这一切都取决于使用情况,这是我评论的重点。但是我认为我们从OP问到的问题离开了这里。顺便说一句。这是一个从你这里到SO的链接到Herb Sutter的Dr.Dobb的并发编程文章,我在这里学到了很多关于虚假共享和其他问题 - 谢谢你。 – iamjoosy