【问题标题】:mmap: enforce 64K alignmentmmap:强制 64K 对齐
【发布时间】:2015-07-14 16:01:57
【问题描述】:

我正在将一个(由我编写的)为 Windows 编写的项目移植到移动平台。

我需要VirtualAlloc (+friends) 的等价物,自然是mmap。但是有 2 个显着差异。

  1. VirtualAlloc 返回的地址保证是所谓的分配粒度 (dwAllocationGranularity) 的倍数。不要与页面大小混淆,这个数字是任意的,在大多数 Windows 系统上是 64K。相比之下,mmap 返回的地址只能保证页面对齐。

  2. 保留/分配的区域可以通过调用VirtualFree 立即释放,无需传递分配大小(即VirtualAlloc 中使用的大小)。相比之下,munmap 应该被赋予要取消映射的确切区域大小,即它释放给定数量的内存页面,而与它们的分配方式没有任何关系。

这给我带来了麻烦。虽然我可以接受(2),但(1)是一个真正的问题。我不想详细说明,但假设分配粒度小得多,例如 4K,将导致严重的效率下降。这与我的代码需要在分配区域内的每个粒度边界放置一些信息有关,这会在连续的内存区域内施加“间隙”。

我需要解决这个问题。我可以考虑分配增加区域的非常幼稚的方法,以便它们可以 64K 对齐并且仍然具有足够的大小。或者保留巨大的虚拟地址空间区域,然后分配正确对齐的内存区域(即实现一种对齐的堆)。但我想知道是否有替代品。例如特殊的 API、可能是一些标志、秘密系统调用或其他任何东西。

【问题讨论】:

    标签: c++ c posix


    【解决方案1】:

    (1) 实际上很容易解决。如您所述,munmap 采用大小参数,这是因为munmap 能够部分 解除分配。因此,您可以分配一块比您需要的更大的内存,然后释放未对齐的部分。

    【讨论】:

    • 这是有道理的!很遗憾我自己没有弄清楚这一点:)
    • P.S.这里的缺点是,在最坏的情况下,我们需要 3 个系统调用而不是 1 个:两端的分配 + 释放。但这似乎没问题...
    【解决方案2】:

    如果可能,请使用posix_memalign(尽管名称是分配而不是对齐内存);这允许您指定对齐方式,并且可以使用free 释放分配的内存。您需要检查您的目标平台是否提供了posix_memalign

    【讨论】:

    • 谢谢。但我更喜欢使用便携的东西。
    • 另一个注意事项:posix_memalign 不保证它会释放未对齐的内存。如果他们不释放未对齐的内存,您将面临大量浪费。例如,glibc 释放未对齐的块除非分配是通过mmap 进行的,在这种情况下是it only adjusts a pointer
    • @valdo mmapMAP_ANONYMOUSposix_memalign 便携性更少;它甚至没有被 POSIX 指定。
    • @nneonneo 当然,但是您只是在浪费地址空间,这很便宜-您实际访问的唯一页面是分配之前的页面,无论如何都必须访问该页面才能存储分配大小.
    • @ecatmur: MAP_ANON 实际上将在未来版本的 POSIX 中标准化。讨论见austingroupbugs.net/view.php?id=850#c2305(注意它已被接受)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多