我正在使用 Haskell Raytracer,并且目前使用 BVH 实现来应用存储层次结构的朴素二叉树。
data TreeBvh
= Node Dimension TreeBvh TreeBvh AABB
| Leaf AnyPrim AABB
Dimension 是 X
、Y
或 Z
(用于更快地遍历),AABB 是我的轴对齐边界框的类型。这个代码已经运行得相当不错了,但我真的很想尽可能快地运行它。所以我的下一步(在使用 C/C++ 时)是使用这棵树构建一个扁平化表示,其中节点存储在数组中,"left" 子节点紧随其父节点,父节点的右子节点的索引与父节点一起存储,因此我有这样的东西:
data LinearNode
= LinearNode Dimension Int AABB
| LinearLeaf AnyPrim AABB
data LinearBvh
= MkLinearBvh (Array Int LinearNode)
我还没有真正地尝试过这个,但我担心性能仍然不够好,因为我不能在 UArray 中存储 LinearNode 实例,也不能将索引右侧子节点的 Int 与组成 AABB 的 Float 值一起存储在单个 UArray 中(如果我理解有误,请纠正我)。而使用两个数组会导致糟糕的缓存协调性。所以我基本上正在寻找一种有效地存储我的树的方法,以便可以期望遍历具有良好的性能。它应该:
- 紧凑
- 具有良好的局部特性
- 与最新版本的 GHC 编译器兼容
- 尽可能少地经过间接访问(通过“thunk”传递无法提高性能,因此我认为“非装箱”类型会有所帮助)
{-# UNPACK #-}
pragma 会有很大帮助。 - Thomas M. DuBuisson