我有一个内存区域,它被划分为预定义BLOCKSIZE
大小的块。给定一个内存块,由其偏移量OFFSET
(以字节为单位)和SIZE
(以字节为单位)定义,如何有效地计算包含此内存块的块数?
例如,让我们说BLOCKSIZE=8
。然后,OFFSET=0
和SIZE=16
的内存块将占用2个块,但OFFSET=4
和SIZE=16
的块将占用3个块。
我可以写一个像这样的公式(在C中使用整数算术):
numberOfBlocks = (OFFSET + SIZE - 1) / BLOCKSIZE - (OFFSET / BLOCKSIZE) + 1;
此计算将需要2个分区和4个添加项。我们可以做得更好吗,只要BLOCKSIZE
是 2的力量以及OFFSET >= 0
和SIZE > 0
?
更新:我理解在这种情况下可以通过改变来取代分裂。
答案 0 :(得分:2)
如果
BLOCKSIZE
是 2的强弱,我们能做得更好吗?
我不这么认为。您的(更正的)公式基本上是(块之后的第一个块的索引) - (第一个包含块的任何部分的索引)。你可以用不同的方式表示它 - 比如,作为块数的基数加上需要一个额外块的某些布局的调整 - 但这实际上增加了一对夫妇所需的操作数量:
numberOfBlocks = (SIZE + BLOCKSIZE - 1) / BLOCKSIZE
+ ((SIZE % BLOCKSIZE) + (OFFSET % BLOCKSIZE)) / BLOCKSIZE;
我没有看到执行(至少)两个整数除法(或等效位移)的任何方法,因为任何计算方法都需要计算两个块计数。这两个计算不能组合,因为每个计算都需要单独的余数截断。
BLOCKSIZE
是2的幂可能有助于您选择更高效的操作,但它无助于减少所需操作的数量。但是,如果您可以依赖SIZE
成为BLOCKSIZE
的倍数,则可以轻微减少操作次数。在这种情况下,你可以这样做:
numberOfBlocks = SIZE / BLOCKSIZE + (OFFSET % BLOCKSIZE) ? 1 : 0;
或者,如果在覆盖的块数上计算上限就足够了,那么你可以这样做:
numberOfBlocksBound = SIZE / BLOCKSIZE + 2;
或在许多情况下略微收紧,但计算成本更高:
numberOfBlocksBound = (SIZE + BLOCKSIZE - 1) / BLOCKSIZE + 1;