mmap:强制执行64K对齐

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

我需要一个等效的VirtualAlloc (+朋友),自然的是mmap 。 但是有两个显着的差异。

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

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

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

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

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

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