mmap:强制执行 64K 对齐
mmap: enforce 64K alignment
我正在将(由我)为 Windows 编写的项目移植到移动平台。
我需要一个相当于VirtualAlloc
(+friends)的,自然是mmap
。然而,有 2 个显着差异。
VirtualAlloc
返回的地址保证是所谓的分配粒度(dwAllocationGranularity
)的倍数。不要与页面大小混淆,这个数字是任意的,在大多数 Windows 系统上是 64K。相比之下,mmap
返回的地址只能保证页面对齐。
reserved/allocated 区域可以通过调用 VirtualFree
立即释放,并且不需要传递分配大小(即在 VirtualAlloc
).相反,munmap
应该给出要取消映射的确切区域大小,即它释放给定数量的内存页面,而与它们的分配方式无关。
这给我带来了麻烦。虽然我可以接受 (2),但 (1) 是一个真正的问题。我不想深入细节,但假设更小的分配粒度(例如 4K)将导致严重的效率下降。这与我的代码需要在分配区域内的每个粒度边界处放置一些信息有关,这将 "gaps" 强加在连续的内存区域内。
我需要解决这个问题。我可以考虑分配增加区域的非常天真的方法,以便它们可以 64K 对齐并且仍然具有足够的大小。或者保留虚拟地址的巨大区域 space,然后分配正确对齐的内存区域(即实现一种对齐的堆)。但我想知道是否有其他选择。例如特殊的 API,可能是一些标志,秘密系统调用等等。
(1) 其实很容易解决。正如您所注意到的,munmap
接受一个大小参数,这是因为 munmap
能够 部分 释放。因此,您可以分配一块比您需要的更大的内存,然后释放未对齐的部分。
如果可能,使用posix_memalign
(尽管名称是分配而不是对齐内存);这允许您指定对齐方式,并且可以使用 free
释放分配的内存。您需要检查您的目标平台是否提供 posix_memalign
。
我正在将(由我)为 Windows 编写的项目移植到移动平台。
我需要一个相当于VirtualAlloc
(+friends)的,自然是mmap
。然而,有 2 个显着差异。
VirtualAlloc
返回的地址保证是所谓的分配粒度(dwAllocationGranularity
)的倍数。不要与页面大小混淆,这个数字是任意的,在大多数 Windows 系统上是 64K。相比之下,mmap
返回的地址只能保证页面对齐。reserved/allocated 区域可以通过调用
VirtualFree
立即释放,并且不需要传递分配大小(即在VirtualAlloc
).相反,munmap
应该给出要取消映射的确切区域大小,即它释放给定数量的内存页面,而与它们的分配方式无关。
这给我带来了麻烦。虽然我可以接受 (2),但 (1) 是一个真正的问题。我不想深入细节,但假设更小的分配粒度(例如 4K)将导致严重的效率下降。这与我的代码需要在分配区域内的每个粒度边界处放置一些信息有关,这将 "gaps" 强加在连续的内存区域内。
我需要解决这个问题。我可以考虑分配增加区域的非常天真的方法,以便它们可以 64K 对齐并且仍然具有足够的大小。或者保留虚拟地址的巨大区域 space,然后分配正确对齐的内存区域(即实现一种对齐的堆)。但我想知道是否有其他选择。例如特殊的 API,可能是一些标志,秘密系统调用等等。
(1) 其实很容易解决。正如您所注意到的,munmap
接受一个大小参数,这是因为 munmap
能够 部分 释放。因此,您可以分配一块比您需要的更大的内存,然后释放未对齐的部分。
如果可能,使用posix_memalign
(尽管名称是分配而不是对齐内存);这允许您指定对齐方式,并且可以使用 free
释放分配的内存。您需要检查您的目标平台是否提供 posix_memalign
。