C++ 移动到64位操作系统时共享内存性能降低

C++ 移动到64位操作系统时共享内存性能降低,c++,windows,winapi,ipc,shared-memory,C++,Windows,Winapi,Ipc,Shared Memory,我对运行在64位windows上的32位旧版应用程序有问题。该应用程序使用CreateFileMapping创建共享内存。在64位Windows上运行时,从另一个进程访问此共享内存的任何尝试大约需要1秒。共享内存是使用页面保护标志创建的: flProtect = PAGE_READONLY | SEC_NOCACHE | SEC_COMMIT; 使用以下方法创建相同内存时: flProtect = PAGE_READONLY | SEC_COMMIT; 问题消失了。目前这种解决方法是可以接受

我对运行在64位windows上的32位旧版应用程序有问题。该应用程序使用CreateFileMapping创建共享内存。在64位Windows上运行时,从另一个进程访问此共享内存的任何尝试大约需要1秒。共享内存是使用页面保护标志创建的:

flProtect = PAGE_READONLY | SEC_NOCACHE | SEC_COMMIT;
使用以下方法创建相同内存时:

flProtect = PAGE_READONLY | SEC_COMMIT;
问题消失了。目前这种解决方法是可以接受的,但我们确实有一些设备需要设置secu_NOCACHE标志

有人能告诉我为什么Secu_NOCACHE会在这种情况下影响性能吗

更新:似乎只有写入此缓冲区的时间增加到了1000ms。阅读似乎没有受到影响。在这段时间内,我们正在向缓冲区写入大约5MB的数据


更新2:此软件用于许多系统,其中一个系统的物理设备需要使用此标志。我们目前仅限于在32位windows中使用此设备运行机器。

我想,因为内存必须从64位重新映射到32位,所以提供“反弹”缓冲区的成本会很高。启用缓存时,此反弹缓冲区是隐式的,操作系统可以避免不断更新内存部分的需要。

您正在使用该标志禁用文件系统缓存。是的,这是一个巨大的区别,它迫使操作系统与磁盘驱动程序一起工作,并直接读取扇区。无法读取和缓存柱面,从而禁用了使读取磁道而无需移动读取头的优化。延迟写回被禁用,这是一种使磁盘写入显示为即时的优化。

下面是关于该标志的说明:

SEC_NOCACHE标志用于 需要各种 锁定结构应位于 永远不会进入的内存 CPU缓存。关于x86和MIPS 机器,使用这个标志只会减慢速度 因为 硬件使缓存保持一致


不幸的是,他们没有量化减速量。

这是一个内存映射文件,不涉及硬盘访问。有。如果为CreateFileMapping的hFile参数指定无效的\u HANDLE\u值,则分页文件将备份该值。请查看SDK文档。为什么会将写入性能从32位更改为64位。如果这是一个大问题,我会不会看到32位的性能也会受到影响?32位代码正在一个名为Wow64的仿真层中运行。实现细节很难获得,这在任何地方都没有文档记录。我怀疑64位驱动程序需要跳转来处理在仿真层中分配的页面。我选择这一点作为答案,因为我认为wow64层中存在一个问题。这是真的,但是在32位中,这种减速不到10毫秒。在64中,它在1000ms的范围内。@Justin:这两个进程都是32位吗?至少在*NIXes上,32位进程创建的共享内存也存在类似的情况,从64位进程访问,反之亦然。顺便说一句,如果引用的文章背后有任何事实,那么扔掉这个标志:Windows现在运行的所有多CPU/核心系统都是显式缓存一致的(不像十年前WinNT 3.5运行的第一个SMP系统)。@Dummy:两个进程都是32位的。谢谢你的多核心观点,我将对此进行研究。我们使用的硬件中只有一个需要此标志,它用于32位系统。目前,我们检查操作系统是32还是64,并设置标志。我只是好奇这种速度减慢的根本原因。这正是我所倾向的,但对于这些操作来说,1000毫秒的时间似乎太长了。反弹缓冲区仅适用于需要32位物理地址的DMA硬件。在用户模式下的32位应用程序中,MMU会进行转换,内存中的任何地址,甚至超过4GB,都可以映射到32位虚拟地址。@ben:即使没有反弹缓冲区,从64位到32位的映射是否会增加这种开销?否,MMU在32位操作系统上的使用方式完全相同。
SEC_NOCACHE
:除非设备明确需要,否则应用程序不应使用此属性。您使用此标志有什么原因吗?您(或最初的实现者)是否误解了它的用途?我们有一个设备需要设置此标志。