缓存感知树实现

Posted

技术标签:

【中文标题】缓存感知树实现【英文标题】:Cache-aware tree impementation 【发布时间】:2017-10-02 08:04:49 【问题描述】:

我有一棵树,其中每个节点可能有 0 到 N 个子节点。

用例是以下查询:给定两个节点的指针:这些节点是否在树的同一分支中?

示例

q(2,7) => true
q(5,4) => false

按书(慢)

直接的实现是在每个节点存储一个指向父节点的指针和一个指向子节点列表的指针。但这会导致性能不佳,因为树会在内存中分段,因此无法识别缓存。

问题

以紧凑的形式表示树的好方法是什么?整棵树大约有 100,000 个节点。所以应该可以找到一种方法让它完全适合 CPU 缓存。

例如二叉树通常是represented implicitly as an array,因此非常适合完全存储在 CPU 缓存中(如果足够小的话)。

【问题讨论】:

【参考方案1】:

您可以预先分配一个连续内存块,您可以在其中连接所有节点的信息。

之后,每个节点只需要一种方法来检索其信息的开头以及该信息的长度。

在这种情况下,每个节点的信息可以由父节点表示,然后是子节点列表(假设我们在没有父节点时使用 -1,ie 表示根节点)。

例如,对于问题中发布的树,节点 1 的信息为:-1 2 3 4,节点 2 的信息为:1 5,依此类推。

通过连接这些数组获得连续数组,结果如下:

-1 2 3 4 1 5 1 9 10 1 11 12 13 14 2 3 5 5 5 3 3 4 4 4 15 4

每个节点都会使用一些元数据来检索其相关信息。如前所述,此元数据需要由startIndexlength 组成。 例如 对于节点 3,我们将有 startIndex = 6length = 3,它允许检索 1 9 10 子数组,表明父节点是节点 1,其子节点是节点 9 和 10。

此外,元数据信息也可以存储在连续的内存块中,在开头。每个节点的元数据都有固定的长度(两个值),因此我们可以很容易地获得某个节点的元数据的位置,给定它的索引。

这样,关于图的所有信息都将存储在一个连续的、缓存友好的内存块中。

【讨论】:

我喜欢它。谢谢!

以上是关于缓存感知树实现的主要内容,如果未能解决你的问题,请参考以下文章

机器学习强基计划1-1:图文详解感知机算法原理+Python实现

实验2 k近邻

基数树RadixTree的golang实现

前端技能树,面试复习第 24 天—— React-Router 了解多少,说一说它的实现原理是什么

基于OneFlow实现量化感知训练

Magnolia“页面感知”缓存