遇到此算法以计算给定地址的页面偏移量。
//naive solution:
int getAlignedValue(int pageSize, int valueToAlign)
{
int index = valueToAlign/pageSize;
return index * pageSize;
}
//faster solution:
int getAlignedValue_Fast(int pageSize, int valueToAlign)
{
return valueToAlign & (~(pageSize-1));
}
天真的方法很简单直观,但更快的解决方案只有在页面大小为2的幂时才有效。例如,
pagesize = 8
address = 30
getAlignedValue(8,30) => 24
getAlignedValue_Fast(8,30) => 24
However, when the pagesize is not a power of 2, such as 10
pagesize = 10
address = 24
getAlignedValue(10,24) => 20
getAlignedValue_Fast(10,24) => 16 //wrong
我的问题是当页面大小为2的幂时,更快的方法使用什么属性,以便valueToAlign & (~(pageSize-1))
“碰巧”返回正确的对齐,例如24.换句话说,从逐位比较中,我所理解的只是它在某种程度上有效,但却没有理解它背后的数学。
//leading 0s are ignored
pagesize = 8 => 00001000, address = 30 => 00011110
=>
~(pagesize - 1) = ~(00000111) = > 11111000
=>
00011110
&11111000
----------
00011000 = 24
非常感谢。
答案 0 :(得分:0)
如果pageSize
是2的幂(即,它只设置了1位),那么~(pageSize - 1)
(相当于大多数系统上的~pageSize + 1
和-pageSize
)仍然具有该特定位,并且所有更高位也被设置:
pageSize = 00001000 // bit k is set
// now the -1 will borrow through all rightmost zeroes and finally reset the 1
pageSize-1 = 00000111 // all bits < k are set
// inverting restores the original 1 and also sets all higher bits
~(pageSize-1)= 11111000 // all bits >= k are set
AND-ing与pageSize
对齐,因为,例如,与8对齐意味着没有设置“值小于8”的位。掩模留下8(在这个例子中)和所有更高的2的幂,但是两个(1,2和4)的所有较低的力被移除。