假设我有一个trie / prefix trie,总数限制为10个节点。我限制为10个节点以模拟超出的内存。 (如果无法将整个树加载到内存中,则总共-磁盘上存储了10个节点。
我现在在Trie中插入一个新字符串,这将导致树超过10个节点的限制,因此现在是时候让LRU缓存从Trie中逐出最近访问最少的节点了。
让我们说树包含单词hello,help,hi,而LRU节点为“ h”。这意味着我需要从特里删除“ h”,在这种情况下,这将删除整个树。我的困惑在于还更新了缓存本身以删除所有子项。在这种情况下如何运作?
我假定高速缓存具有“ h”,“ he”,“ hel”,“ help”等节点。如果删除“ h”节点,则假定需要删除高速缓存中所有以“ H”?我的整个假设似乎效率很低。
答案 0 :(得分:0)
在谈论缓存时要记住的一件事是它是一个冗余的数据结构,其唯一目的是加快数据提取的速度。
因此,当从高速缓存中逐出一条数据时,它对使用该数据的程序没有任何影响(执行速度除外),因为它随后将从主存储器中获取。因此,无论如何,您的特里树都将具有完全相同的行为,而不管它的哪一部分位于缓存中。
这非常重要,因为它允许我们使用高级语言(例如java)进行编码,而无需关心处理器实现的缓存的替换策略。如果不是这种情况,那将是一场噩梦,因为我们必须考虑到处理器中实施的所有现有(以及将来的?)更换政策。甚至没有提到这些策略不像LRU那样简单(存在缓存集,将缓存分为“行”,并且它们的行为也与它们的物理结构密切相关),并且放置了一部分数据高速缓存中的地址取决于其在主存储器中的地址,对于每个代码执行而言,地址不一定相同。
简而言之,您提到的两件事(java中的trie节点和LRU缓存策略)相距太远(一件事是非常非常低级的编程,另一件事是高层次的编程)。这就是为什么我们很少考虑它们之间的相互作用的原因。 PS:在您的文章中,您谈到模拟正在执行的内存。程序没有这样的东西。当缓存已满时,我们将填充主内存。当主内存已满时,操作系统通常会保留一部分硬盘驱动器以发挥主内存的作用(我们称其为交换,当发生交换时,计算机的性能与冻结一样好)。当交换已满时,程序崩溃。全部都是
在程序的“思想”中,操作系统为它提供了绝对巨大的内存量(这是虚拟的,但对于程序来说,它与真实的一样好),永远不会被填满。程序本身并不“知道”内存的管理方式以及剩余的内存量,原因有很多(安全性,请确保所有程序在资源中都有公平的份额……)>