【发布时间】:2017-06-13 17:24:40
【问题描述】:
根据包括Wikipedia 在内的多个来源,实现二叉树最常用的两种方法是:
- 节点和指针(或引用),每个节点显式拥有其子节点。
- 数组,其中子节点的位置由其父节点的索引隐式给出。
第二个显然在内存使用和引用位置方面更胜一筹。但是,如果您要允许从树中插入和移除,可能会导致树不平衡。这是因为这种设计的内存使用量是树深度的指数函数。
假设您希望支持此类插入和删除。如何实现树,以便树遍历充分利用 CPU 缓存。
我正在考虑为节点创建一个对象池并将它们分配到一个数组中。这样节点将靠近在一起->因此具有良好的参考位置。
但是如果节点的大小和缓存行的大小一样,这有什么意义吗?
如果您的 L1 行大小为 64 字节,并且您访问 std::vector<std::uint8_t>(64) 的第一个成员,您可能会将向量的全部内容保存在 L1 缓存中。这意味着您可以非常快速地访问任何元素。但是如果元素的大小与缓存行大小相同怎么办?由于 L1、L2 和 L3 高速缓存的高速缓存行是 likely not to be very different,因此在这里引用位置似乎没有任何帮助。我错了吗?还有什么可以做的?
【问题讨论】:
-
“第二个显然在几乎任何意义上都优于”除了缓存之外 - 为什么?
-
@NeilButterworth 这对我来说是一件愚蠢的事情。我试图让它更精确。如果您有其他建议,请随时编辑。
-
可能是 std::deque 而不是 std::vector(或数组)。 “典型的实现使用一系列单独分配的固定大小的数组。”来自en.cppreference.com/w/cpp/container/deque 还检查了 std::vector 的性能(将尝试找到这个参考) - 使用 std 的随机插入/删除::vector 与 std::list 相比,向量在最多 100,00 个元素(大约)时表现更好
-
发现它“现代 C++:你需要知道的 - Herb Sutter”,从演示开始大约 46 分钟开始channel9.msdn.com/Events/Build/2014/2-661
标签: c++ memory-management data-structures binary-tree cpu-cache