【问题标题】:Flattening a tree into a linked list c++, without pointers将树展平为链表 C++,没有指针
【发布时间】:2013-04-24 09:21:00
【问题描述】:

我正在研究一种遗传算法,我想尝试将一些函数放入 cuda 中,看看是否可以实现值得的加速。

目前的数据结构是一棵节点树,其中函数节点包含指向它们可能拥有的任何子节点的指针向量。我相信我需要将这棵树折叠成一个链表,可能是节点的向量(不是指针)。这些节点将包含指向其子节点的整数索引列表。通过这种方式,我可以将结构按值传递给 cuda。

  root/             (0)
  ├── add           (1)
  │   ├── 5         (2)
  │   └── divide    (3)
  │       ├── 10    (4)
  │       └── 5.7   (5)
  └── multiply      (6)
      ├── 1.2       (7)
      └── 77        (8)

它可以很容易地展平,但我担心进行这些更改将需要一些自定义函数,并且可能比 node->childNode[x] 样式结构的计算成本更高。

例如,如果我想用数字 7 替换除法及其子结构,我需要:

  • 流行成员 4,5
  • 将索引 3 处的除数更改为数字 7。
  • 更新根函数,使其第二个子函数的引用现在为 4。
  • 更新乘法函数,现在在 4,即子节点现在在 5 和 6

一定有更好的方法吗?我不是 c++ 专家,所以我正在寻找建议和代码示例会非常有帮助!

【问题讨论】:

  • C++ 中没有指针的链表?我认为指针在这种情况下通常很有用。
  • 同意,但我相信指针一旦传递到 GPU 内存将无效。这就是为什么我想折叠成一个对象向量
  • 只要你不关心动态增长你的数据结构,你总是可以用索引替换指针到数组中。

标签: c++ data-structures cuda tree linked-list


【解决方案1】:

我建议保持你的树结构完全不变,除了用数组中的索引替换你的指针,如 tera 所说。

我在说什么数组?您需要设置一个内存池(又名固定大小块分配器)。你可以谷歌这个。池基本上是一个包含任何节点类型的数组。您应该提前选择最大大小(树中需要的最大节点数)。然后,您将永远不必调整/增长这个数组。您的内存池类将具有 allocate 和 free 方法,但它们对数组的索引进行操作,而不是指针。

使用这种方法,您将能够非常便宜地进行您提到的树修改 - 使用内存池,分配和删除项目非常便宜,并且您永远不会在内存中复制/移动节点。

您将把树的根(同样,只是一个索引,而不是一个指针)连同内存池的数组一起传递给 GPU。

【讨论】:

  • 您好,埃里克,感谢您的回复。这听起来很有希望,我会在今天晚些时候尝试一下
  • 我在谷歌上搜索了一下,我很确定这是正确的答案,但我找不到一个易于遵循的实现。我暂时选择了一个向量,因为大部分工作都是插入到最后。过几天我会再去看看,如果你知道有什么好的资源请告诉我
  • 这是一个实现。它使用 1 个 stl 向量和 1 个 c 样式数组。这基本上就是我所描述的。构造函数参数“nSize”是我讲的最大数组大小:codeproject.com/Articles/359640/…
  • 这是一个更聪明的实现,它只使用 1 个数组,因为它就地存储空闲列表:molecularmusings.wordpress.com/2012/09/17/…
  • 选择了第一个选项。工作得很好,代码感觉更干净。我已经能够将我要尝试的每个对象的向量拖放到 Cuda 中。 + 即使使用池分配,一个循环也快了大约 10%,所以我想一旦程序运行多个循环,我也会看到一个很好的加速。
猜你喜欢
  • 1970-01-01
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 2020-01-08
  • 2013-08-31
  • 2013-08-26
相关资源
最近更新 更多