【问题标题】:Is there difference between Cache index address calculation vs Division hash function?缓存索引地址计算与分区哈希函数有区别吗?
【发布时间】:2017-01-13 08:54:51
【问题描述】:

在从计算机体系结构中研究哈希数据结构和缓存内存时,我注意到它们非常相似。

除法哈希函数通过 hash(k) = k Mod (table size M) 计算索引,但我的 DS 书说 M 应该是素数或至少是奇数,因为如果 M 是偶数,结果是当 k 为偶数时总是偶数,当 k 是奇数时是奇数,所以应该避免偶数 M,因为你经常使用总是偶数的内存地址。

然而,我的 CA 书说对于直接映射缓存,您使用(块地址)Mod(缓存中的块数)并且结果索引看起来一致。为什么是这样?这一切都非常令人困惑,因为 MIPS 每 4 个字节使用 32 位地址,这是偶数。但我认为这是因为它们丢弃了最后 2 位,因为它们是字节偏移量?

而且,由于它使用(块地址)Mod(缓存中的块数),它使缓存大小为2的幂,因此您可以只使用块地址的低x位。

但是这个方法看起来和除法哈希函数完全一样,除了你使哈希表的幂为2,它是偶数(数据结构书说使用质数或奇数)并使用块地址的低位.

这是两种不同的方法吗?如果是这样,缓存的名称是什么?非常感谢您的回复。谢谢。

【问题讨论】:

    标签: caching data-structures hash cpu-architecture


    【解决方案1】:

    here 描述了哈希表不使用偶数的原因。 here 描述了缓存如何使用地址来计算行号。缓存可以将多个条目映射到同一行。仅仅因为一个地址被映射到一个有数据的缓存行,我们就不会盲目地使用那个缓存行中的数据。我们还进行了标签比较,以确保缓存行的内容正是我们要查找的内容。

    【讨论】:

    • 这根本不能回答我的问题。无关紧要,第一个链接是完全错误的。发生这种情况是因为您使用了大于键值的 M。它必须更小,以便可以提取较低的位。
    【解决方案2】:

    使用素数取模的原因是为了得到位的“混合”,如果你要散列的整数结构不好,这很有帮助。这不是处理它的唯一方法,例如 Java 标准库不使用它,它使用单独的“混合”函数(将输入与自身的右移版本进行异或)然后使用两个大小的幂表。无论哪种方式,它都可以防止严重分布的输入,这本身并不是必需的 - 如果输入总是很好地分布,你就不需要它。

    内存地址通常分布得相当好,因为它通常用于连续片段。明显的例外是您会看到高度对齐的大对象,如果不对其进行任何处理,它们会在缓存中相互冲突。当然,您可能会使用组关联缓存而不是直接映射,因为它对降级的鲁棒性要强得多,并且可以解决很多问题。但是没有什么可以免受不良模式的影响(这也适用于 hash-mod-prime,如果你知道素数,你可以轻松击败它),但是一个相当简单的改进(它也在实践中使用,或者至少是,更多现在存在先进的技术 - 与减轻不良访问模式的自适应替换策略相结合)是将一些较高地址位异或到索引中。这是哈希强化,与 Java 标准库中使用的技术相同,但它的版本要简单得多。

    在这种情况下,您不想用素数(或实际上不是 2 的幂的任何东西)计算余数,它本身的计算速度很慢,而且会给您带来尴尬大小的缓存没有充分利用其解码器的功能,这会增加速度(或减少给定延迟的缓存大小,具体取决于您如何看待它)。这与将一些高位异或到低位之间的区别在硬件中比在软件中要大得多,因为异或实际上是硬件中的一项微不足道的操作,电路操作比指令快得多。

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 2013-09-22
      • 1970-01-01
      • 2019-04-17
      • 2013-07-29
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 2011-08-31
      相关资源
      最近更新 更多