为什么内存管理器使用 (size + PAGE_SIZE-1) / PAGE_SIZE 来计算要分配的页数?
Why do memory managers use (size + PAGE_SIZE-1) / PAGE_SIZE to calculate the number of pages to allocate?
我在不同的地方多次遇到这样的公式(例如;Linux kernel 和 glibc)。为什么他们使用这个公式而不是简单地:
pages = (size / PAGE_SIZE) + 1;
作为一个猜测,我认为上面公式的问题是当大小 PAGE_SIZE
对齐(PAGE_SIZE
的倍数)时,因为在这种情况下,它会报告多一页超出需要,因此我们还必须这样做:
pages = (size / PAGE_SIZE) + 1;
if (!(size & (PAGE_SIZE-1))) /* is size a multiple of PAGE_SIZE? */
pages--;
这显然比 (size + PAGE_SIZE-1) / PAGE_SIZE
!
更多的代码
是的,用于取除法结果的上限,即商向上取整
的问题
pages = (size / PAGE_SIZE) + 1;
if (!(size & (PAGE_SIZE-1))) /* is size a multiple of PAGE_SIZE? */
pages--;
不仅代码多了很多,而且
- 由于分支
,它的性能更差
- 它只适用于 2 的幂
当然,二进制计算机中的页面大小始终是 2 的幂,但是 (size + PAGE_SIZE-1) / PAGE_SIZE
适用于除数的任何值
另见
- Fast ceiling of an integer division in C / C++
- Rounding integer division (instead of truncating)
- Dividing two integers and rounding up the result, without using floating point
- What's the right way to implement integer division-rounding-up?
这是四舍五入。您将 (PAGE_SIZE - 1)
添加到 nbytes
所以如果您有 PAGE_SIZE
nbytes
的确切数量,那么您将获得所需的最少页数,如果您将它传递给一个,然后你会得到一个新页面,为额外的字节提供 space。
还有一种方法是用log2的页面大小。在Linux内核源码中,是PAGE_SHIFT。例如,如果 PAGE_SIZE 为 4096 = 2^12 字节,则 PAGE_SHIFT 为 12(即 log2(2^ 12)).因此,要获得给定 size 的 pages 的数量,通常使用以下公式:
页数 = (大小 + PAGE_SIZE - 1) >> PAGE_SHIFT
顺便说一下,页面大小通常定义为:
#define PAGE_SIZE (1 << PAGE_SHIFT)
我在不同的地方多次遇到这样的公式(例如;Linux kernel 和 glibc)。为什么他们使用这个公式而不是简单地:
pages = (size / PAGE_SIZE) + 1;
作为一个猜测,我认为上面公式的问题是当大小 PAGE_SIZE
对齐(PAGE_SIZE
的倍数)时,因为在这种情况下,它会报告多一页超出需要,因此我们还必须这样做:
pages = (size / PAGE_SIZE) + 1;
if (!(size & (PAGE_SIZE-1))) /* is size a multiple of PAGE_SIZE? */
pages--;
这显然比 (size + PAGE_SIZE-1) / PAGE_SIZE
!
是的,用于取除法结果的上限,即商向上取整
的问题pages = (size / PAGE_SIZE) + 1;
if (!(size & (PAGE_SIZE-1))) /* is size a multiple of PAGE_SIZE? */
pages--;
不仅代码多了很多,而且
- 由于分支 ,它的性能更差
- 它只适用于 2 的幂
当然,二进制计算机中的页面大小始终是 2 的幂,但是 (size + PAGE_SIZE-1) / PAGE_SIZE
适用于除数的任何值
另见
- Fast ceiling of an integer division in C / C++
- Rounding integer division (instead of truncating)
- Dividing two integers and rounding up the result, without using floating point
- What's the right way to implement integer division-rounding-up?
这是四舍五入。您将 (PAGE_SIZE - 1)
添加到 nbytes
所以如果您有 PAGE_SIZE
nbytes
的确切数量,那么您将获得所需的最少页数,如果您将它传递给一个,然后你会得到一个新页面,为额外的字节提供 space。
还有一种方法是用log2的页面大小。在Linux内核源码中,是PAGE_SHIFT。例如,如果 PAGE_SIZE 为 4096 = 2^12 字节,则 PAGE_SHIFT 为 12(即 log2(2^ 12)).因此,要获得给定 size 的 pages 的数量,通常使用以下公式:
页数 = (大小 + PAGE_SIZE - 1) >> PAGE_SHIFT
顺便说一下,页面大小通常定义为:
#define PAGE_SIZE (1 << PAGE_SHIFT)