4

是否有人对不将自身限制在标准 win32 内存地址空间的自定义数据(delphi 集合、二叉树、DIContainers 等)的存储和处理有任何建议(产品、工具集、方法或其他)?更极端地说,有没有现成的东西可以做相当于持有 10GB TList 的东西,从而打破 /3GB 开关障碍和 4GB 的“windows on windows”限制?

理想情况下,我们需要的是对 Delphi 应用程序程序员非常透明的东西,但允许非常快速地访问其结构中保存的数据,最好是通过键查找。相当于一个 delphi 收集容器就可以了,但它的内存使用需要通过 AWE。它还需要处理映射和取消映射它使用的物理空间到使用它的win32进程中,即那将是透明位......

将数据移入数据库并不是解决办法——信息需要保持在内存中,以便快速访问。我们尝试过的内存数据库/表没有使用 AWE,而且访问速度也很慢。我们当前的 Delphi 数据结构很好,但会超出 win32 地址空间的限制。

4

7 回答 7

2

我将成为一个彻头彻尾的笨蛋,并告诉你我已经做了一些比你所描述的更先进的东西......在工作中。所以恐怕都是封闭源代码。从来没有在任何地方看到过这样的事情。我们将 VM、AWE、MMF 和(很快)32<>64 位 IPC 组合成一个大型平均数据处理机器,可处理高达 64 GB 的内存,同时处理数百个数据集,每个数据集数十 GB 。

但我可以给你一些提示:AWE 视图交换相当慢,因为它在交换期间强制暂停所有正在运行的线程。因此,明智地选择你的窗口大小(越小,交换越快 - 但调用开销越低,当然越大)。我们已经确定 AWE 视图大小等于 Windows 默认页面大小 (4 KB),但这只是因为随机访问以这种方式执行得最好。Lineair 数据访问可以在更大的视图尺寸下运行得更快。

每个视图都可以映射到分配的 AWE 内存的任何部分,因此可以帮助的一件事是仅将那些页面映射到需要访问的视图中 - 并尝试节省不必要的视图交换(优先级队列浮现在脑海中) )。

此外,您的设计中应该有一个注册机制来处理视图和其背后的 AWE 内存之间的链接。这最好是线程安全的!

至于一般用法:不,这不适合常规的 Delphi 类。您应该完全切换到另一个概念 - 并以此为基础构建您的数据结构。

不管怎样,祝朋友好运!您将需要它... ;-)

于 2009-10-07T21:57:28.640 回答
0

AWE 的问题与旧的、基于 DOS 的 EMS 和 XMS 非常相似——如果你曾经使用过它们的话。基本上是保留一段可寻址内存,然后在需要时将可寻址范围外的内存映射到可寻址范围,不再需要时取消映射,允许其他内存映射到相同的地址。因此,大多数非 AWE 感知数据结构或容器在这种情况下都无法工作 - 可能 TMemoryStream 后代更容易构建。构建将数据存储在 AWE 内存中的 TList 等应该很容易,它应该跟踪数据的实际存储位置并在需要时调用它们,并在数据映射到可寻址内存时调整地址。我不知道任何使用 AWE 的 Delphi 容器库,还有另一个问题:物理RAM,需要服务器版本,支持的物理 RAM 取决于使用的版本,完整列表请参见此处

于 2009-09-14T21:48:54.620 回答
0

假设数据被批量加载一次并适合可用内存,NexusDB AWE 将非常非常快。该数据库可以创建为仅内存中的数据库,然后在操作时不需要任何进一步的硬盘访问。

于 2009-09-14T21:51:56.283 回答
0

有一些系统调用可以做到这一点,但并非所有版本的 Windows 都支持它(特别是 Windows XP 不支持 AWE)。

透明度将是一个问题,因为 API 无法返回指向对象的指针。将超过 4GB 的 RAM 映射到 4GB 的地址空间意味着 32 位指针可能不明确 - 您可能会将不同的对象映射到同一位置。

这种模糊性意味着您必须为持有可用于访问“记录”的句柄的对象生成代理。某些 SQL Server 版本使用此技术将磁盘缓冲区存储在 AWE 内存中。像这样的方法可能适用于矩阵中的行,其中对整行进行操作。更细粒度的访问会更加繁琐。

为了提供对映射对象的直接访问,您必须实现一个协议,其中可以使用指向映射内存的临时指针。这还需要在使用时将对象锁定在内存中 - 再一次,你的透明度会爆炸。

假设您现在可以获得 64 位版本的 Delphi,对于需要更多 RAM 的客户,您最好选择 64 位版本的 Windows。

于 2009-09-14T13:31:44.083 回答
0

您说您不想迁移到数据库,但是专门使用 AWE的数据库呢?

我没有亲自尝试过,但会考虑将这家公司的产品用于我自己的项目。

[编辑]:NexusDB 对 Delphi 友好:它起源于旧的 Turbopower FlashFiler 开发(但从那时起已经走了很长一段路)。

于 2009-09-14T13:35:14.380 回答
0

您的情况听起来与我们的情况相似,我们的应用程序使用了一个巨大的数据文件,我们将其存储在内存映射文件中。这些文件大约 750MB,我们从中分配数据结构,最多使用 1.5GB 的 RAM。

不幸的是,我们没有找到解决 4GB 限制的解决方案,只是将其中的一部分移到 FPC/Lazarus 直到 Delphi 为 64 位。AWE 不适用于 Vista Home 版本,我们也无法使其与 MMF 一起使用。

您可以尝试使用滑动窗口的内存映射文件,这意味着您可以根据应用程序正在使用文件的哪个部分来动态创建文件不同块的视图。听起来那行不通,因为您需要一次将整个文件保存在内存中。

于 2009-12-01T21:10:04.260 回答
0

在我看来,你们可能会考虑放弃当前的数据库 SQL 后端并采用 100% NexusDB + AWE 解决方案。

(或者更确切地说,放弃对 SQL 后端的日常访问,并拥有一个导出/同步功能,可以将任何所需的 NexusDB 报告数据写入 MSSQL 报告数据库。)

W

于 2009-12-01T13:38:41.167 回答