Skip to content

模型Model

缓存无关搜索树

施工中 · 内容逐步修订

cache-oblivious search tree

在程序不知道块大小与缓存容量时,通过递归布局使搜索在各级存储上同时获得对数块传输界。

形式陈述 ​

模型、接口与目标 ​

在缓存无关模型中,数据以块大小 B 在慢存与容量 M 的快存之间传输,但算法代码不读取 B 或 M。静态有序字典支持 search、predecessor 和 successor;动态版本还需 insert、delete 与区间扫描。

本页的静态构造选取二叉搜索树;动态 cache-oblivious B-tree 另需后文说明的维护结构。令 N≥1、B≥2,并假设缓存至少容纳常数个块。静态搜索的目标是

O(1+logB⁡N)

次 I/O,同时做 O(log⁡(N+1)) 次比较。分析采用 ideal-cache:块自动调入,缓存全相联,并以最优替换衡量 misses。递归算法常在 M=Ω(B1+δ) 的 tall-cache 条件下证明批量更新或扫描界;具体结论若无需该条件,也应单独说明,而不是把所有操作共享一个模糊假设。

静态树的 vEB 递归布局 ​

先对排序键递归选取中位数,构造高度为 ⌈log2⁡(N+1)⌉ 的二叉搜索树,再补成同高度的完美树,空位不存真实键,补齐后仍只有 O(N) 个节点,再按van Emde Boas 布局存入连续数组。对高度 h 的树,在中间高度切开:递归摆放 top tree,然后按从左到右的边界次序递归摆放各棵 bottom subtree。

搜索仍按比较结果从根走向叶,变化的是节点地址。布局递归没有一层写着“每块放 B 个节点”;它同时让许多高度尺度的子树连续,因此可在分析时针对真实 B 选择恰当尺度。

块传输界的不变量 ​

固定任意 B≥2,沿布局递归在节点数首次不超过 B 时停止。每个停止片段连续存放,即使未对齐也至多跨两个块。若其父递归片段超过 B,父高度至少为 log2⁡(B+1);分半后的高度仍为 Ω(log⁡B),而片段至多 B 个节点又给出 O(log⁡B) 的高度上界。因此高度 O(log⁡N) 的路径至多穿过

O(1+log⁡Nlog⁡B)=O(1+logB⁡N)

个这样的路径片段。

每个片段只引起常数次块传输,得到搜索界;整树已经不超过一个块大小时,常数项覆盖首次装入。空字典直接返回无匹配,不计算 log⁡0。证明重心是“某个合适尺度的递归子树连续”,并非笼统的“递归会有局部性”。若节点由普通堆分配器逐个随机放置,逻辑递归关系不再带来地址连续性,论证也随之消失。

直觉

普通二叉搜索树的逻辑路径只有 O(log⁡N) 个节点,但随机地址可能让每个节点各触发一次 I/O。vEB 布局把多种高度的完整子树递归地放成连续片段;无论块实际能容纳多少节点,总能在某个递归尺度上让一块覆盖路径的若干层,于是块传输数从 log⁡N 降为 logB⁡N。

vEB 布局中的搜索路径与块传输
例子与边界

查询 11 的可追踪例子 ​

把键 1,…,15 排成完美平衡树,根为 8;右子树根为 12,其左孩子为 10,10 的右孩子为 11。查询 11 的比较路径为

8→12→10→11.

层序数组会把 8、12、10、11 放在下标 1、3、6、13 附近,越到深层距离越大。vEB 布局先连续递归放上半树,再放下半子树;对于能容纳约四个节点的块,路径中的相邻若干层会被同一个递归片段覆盖。

这个例子不声称四个节点必然恰落在一个对齐块内。数组起始地址可能使连续片段跨块,所以证明按常数块而非“一块”计数;渐近界不依赖幸运对齐。

predecessor 与扫描 ​

本页的 predecessor 返回不大于查询键的最大已存键:沿路径保留最后一个合适候选,比较相等时即可返回;无候选时报告无前驱。successor 对称地返回不小于查询键的最小成员。两者都只访问一条根叶路径,继承相同 I/O 界;严格前驱或严格后继则须排除相等项。

区间扫描需要额外的叶序结构。若布局把中序叶或记录区连续存储,定位首键后可用 O(K/B+1) 次 I/O 输出 K 个结果;仅有 vEB 形状布局并不自动保证报告记录连续。把 search 的路径界直接写成 range query 的输出界,会漏掉这一接口条件。

推论与应用

动态维护为何是另一项技术 ​

静态数组插入一个键可能移动大量后缀,树旋转也会破坏递归片段。动态缓存无关搜索树通常把有序记录放入 packed-memory array,以分层密度阈值控制局部重排,再用缓存无关搜索索引定位区域;更完整的 cache-oblivious B-tree 还要协调分裂、重建和扫描。

密度不变量要求每个层级区间的占用率落在相应上下界。插入先利用附近空隙;区间过密时逐级扩大重排范围。由多次局部更新摊分重排成本,而不是从静态 O(logB⁡N) 搜索界“顺便”推出便宜更新。

与已知结构的对照 ​

传统 B-tree 明确知道 B,把一个节点设计成约一个块并用高扇出降低树高。缓存无关搜索树以二叉比较路径和递归地址布局适配多个未知层级,常数、重建成本与实现复杂度不同。

排序数组也有优秀的顺序扫描局部性,二分搜索却可能在每一层跳到远处;合适的 cache-oblivious 静态布局改善的是搜索路径。名称中的 vEB 指 layout,不是按整数宇宙递归、支持 predecessor 的 van Emde Boas 集合。

适用边界 ​

界依赖记录大小固定或可受控,使 Θ(B) 个节点确实对应一个块尺度。可变长对象、间接指针、垃圾收集移动和并发修改都需要额外布局协议。ideal-cache 的最优替换是分析基准,不代表真实硬件会执行同一策略;硬件预取、TLB 与缓存组相联会改变常数。

因此页面级结论应分开报告:静态查找可由 vEB layout 达到 O(1+logB⁡N) I/O;动态更新需要额外结构及其自身假设;并发与持久化不在经典模型保证内。

参考资料
  • Harald Prokop, Cache-Oblivious Algorithms, MIT Master's Thesis, 1999.
  • Michael A. Bender, Erik D. Demaine and Martin Farach-Colton, Cache-Oblivious B-Trees, SIAM Journal on Computing, 2005.
  • Matteo Frigo, Charles E. Leiserson, Harald Prokop and Sridhar Ramachandran, Cache-Oblivious Algorithms, ACM Transactions on Algorithms, 2012.
关系图谱10 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
分类位置

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。

类型化关系