我正在研究一种遗传算法,我想尝试将一些函数放入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,我需要:
- pop members 4,5
- 将索引3处的除法改为数字7。
- 更新根函数,使其第二个子函数的引用现在为4。
- 更新乘法函数,现在是4,也就是说子节点现在是5和6
一定有更好的办法吧?我不是一个c++专家,所以我正在寻找的建议和代码示例将是非常有帮助的!
我建议你的树结构完全保持原样,除了用索引替换指针到数组中,如tera所说。
我说的是什么数组?您需要设置一个内存池(又名固定大小块分配器)。你可以谷歌一下。池基本上是节点类型的数组。您应该提前选择最大大小(树中需要的最大节点数)。然后,您将永远不必调整/增长这个数组的大小。您的内存池类将具有allocate和free方法,但这些方法操作的是数组的下标,而不是指针。
使用这种方法,您将能够非常便宜地完成您提到的树修改—使用内存池,分配和删除项非常便宜,并且您永远不会在内存中复制/移动节点。
您将传递树的根(再次,只是索引,而不是指针)到GPU,以及内存池的数组。