Language agnostic 内存映射文件的优点是什么?

Language agnostic 内存映射文件的优点是什么?,language-agnostic,memory,filesystems,Language Agnostic,Memory,Filesystems,我一直在为一个项目研究内存映射文件,如果有人曾经使用过它们,或者决定不使用它们,我会非常感激,为什么 我特别关注以下几点,按重要性排序: 并发性 随机存取 演出 易用性 便携性 并发性将是一个问题。 随机访问更容易 性能从好到好。 易用性。没有那么好。 便携性-不那么热 很久以前我就在Sun系统上使用过它们,这就是我的想法。内存映射文件可以用来取代读/写访问,也可以用来支持并发共享。当你将它们用于一种机制时,你也会得到另一种机制 与在文件中查找、写入和读取不同,您可以将文件映射到内存中,只需访

我一直在为一个项目研究内存映射文件,如果有人曾经使用过它们,或者决定不使用它们,我会非常感激,为什么

我特别关注以下几点,按重要性排序:

  • 并发性
  • 随机存取
  • 演出
  • 易用性
  • 便携性

    • 并发性将是一个问题。 随机访问更容易 性能从好到好。 易用性。没有那么好。 便携性-不那么热


      很久以前我就在Sun系统上使用过它们,这就是我的想法。

      内存映射文件可以用来取代读/写访问,也可以用来支持并发共享。当你将它们用于一种机制时,你也会得到另一种机制

      与在文件中查找、写入和读取不同,您可以将文件映射到内存中,只需访问您期望的位

      这可能非常方便,并且取决于虚拟内存接口可以提高性能。性能的提高是因为操作系统现在可以管理以前的“文件I/O”以及所有其他编程内存访问,并且可以(理论上)利用分页算法等,它已经在使用这些算法来支持程序其余部分的虚拟内存。但是,它确实取决于底层虚拟内存系统的质量。我听说Solaris和*BSD虚拟内存系统可能比Linux的VM系统表现出更好的性能改进,但我没有经验数据支持这一点。YMMV

      当您考虑多进程通过映射内存使用相同的“文件”的可能性时,并发。在读/写模型中,如果两个进程向文件的同一区域写入数据,您可以非常确定该进程的一个数据将到达该文件,从而覆盖另一个进程的数据。你会得到一个,或者另一个,但不是一些奇怪的混合。我必须承认,我不确定这是否是任何标准强制要求的行为,但这是你可以非常依赖的。(这实际上是一个很好的后续问题!)

      相反,在映射的世界中,想象两个过程都是“写作”。它们通过执行“内存存储”来实现这一点,最终导致O/S将数据分页到磁盘。但与此同时,可能会发生重叠写入

      这里有一个例子。假设我有两个进程,都在偏移量1024处写入8字节。进程1正在写入“11111111”,进程2正在写入“2222”。如果他们使用文件I/O,那么您可以想象,在O/S的深处,有一个满1的缓冲区和一个满2的缓冲区,它们都指向磁盘上的同一个位置。其中一个先到,另一个再到。在这种情况下,第二个赢了但是,如果我使用内存映射文件方法,进程1将执行一个4字节的内存存储,然后是另一个4字节的内存存储(假设这不是最大内存存储大小)。过程2将做同样的事情。根据进程运行的时间,您可能会看到以下任何情况:

      11111111
      22222222
      11112222
      22221111
      
      解决这个问题的办法是使用显式互斥——这在任何情况下都可能是个好主意。无论如何,在读/写文件I/O的情况下,您有点依赖O/S来做“正确的事情”

      分类互斥原语是互斥。对于内存映射文件,我建议您使用(例如)pthread_mutex_init()查看内存映射互斥体


      使用映射文件进行编辑:当您使用映射文件时,会有一种诱惑,即在文件本身中嵌入指向文件中数据的指针(想想存储在映射文件中的链表)。您不希望这样做,因为文件可能在不同的时间或在不同的进程中映射到不同的绝对地址。相反,在映射文件中使用偏移量。

      我使用内存映射文件在用户键入时实现了“自动完成”功能。我在一个索引文件中存储了超过100万个产品零件号。该文件具有一些典型的头信息,但文件的大部分是按键字段排序的固定大小记录的巨大数组

      在运行时,该文件是内存映射的,转换为
      C
      -style
      struct
      数组,我们进行二进制搜索以查找与用户类型匹配的零件号。实际上,从磁盘上只读取了文件中的几个内存页——在二进制搜索过程中命中的任何一页

      • 并发性——我遇到了一个实现问题,它有时会在同一个进程空间中多次映射文件的内存。我记得这是一个问题,因为有时系统找不到足够大的可用虚拟内存块来映射文件。解决方案是只映射一次文件,然后关闭对它的所有调用。回想起来,使用成熟的Windows服务当然很酷
      • 随机存取-二进制搜索当然是随机存取和闪电般的快速
      • 性能-查找速度非常快。当用户键入一个弹出窗口显示匹配的产品零件号列表时,该列表会随着用户继续键入而缩小。打字时没有明显的滞后

      我认为它的优势在于,与传统的读取文件方法相比,可以减少所需的数据复制量

      如果您的应用程序可以在内存映射文件中“就地”使用数据,则无需复制即可进入;如果您使用系统调用(例如Linux的pread()),那么这通常涉及内核将数据从自己的缓冲区复制到用户空间。这种额外的复制不仅需要时间,而且通过访问数据的额外副本降低了CPU缓存的效率

      如果实际必须从光盘读取数据(如物理I/O)