Cuda 基于GPU的4D数据分割

Cuda 基于GPU的4D数据分割,cuda,4d,labeling,Cuda,4d,Labeling,我面临的问题是分割大型数据集(高达2048x2048x40x10000x,y,z,t==解压后的几个terrabytes,给定或获取)。从好的方面来说,这个数据集中的特征非常小;最大20x20x20x20左右 就我所知,没有现成的解决方案(如果我错了,请纠正我)。我有一些解决这个问题的计划,但我希望得到你的反馈 一个时间片的最大容量约为600mb;典型情况下较少;我可以在4gb内存中保存一堆这样的片 考虑到我的特征尺寸很小,我的直觉告诉我最好避免所有形式的分割技巧,只需对我的标签进行局部迭代的泛

我面临的问题是分割大型数据集(高达2048x2048x40x10000x,y,z,t==解压后的几个terrabytes,给定或获取)。从好的方面来说,这个数据集中的特征非常小;最大20x20x20x20左右

就我所知,没有现成的解决方案(如果我错了,请纠正我)。我有一些解决这个问题的计划,但我希望得到你的反馈

一个时间片的最大容量约为600mb;典型情况下较少;我可以在4gb内存中保存一堆这样的片

考虑到我的特征尺寸很小,我的直觉告诉我最好避免所有形式的分割技巧,只需对我的标签进行局部迭代的泛洪填充式更新;如果你的邻居有更高的标签,复制它;迭代直到收敛。迭代次数应以任何维度中的最大集群大小为界,该最大集群大小也应较小

CUDA对3D有着天然的偏好,所以我可以分两步完成这项工作;迭代所有尚未收敛的三维体积切片。然后简单地在所有连续的时间片上执行元素级循环,并执行相同的泛光填充逻辑

我可以用一个简单的递增唯一计数器初始化迭代,或者先找到局部最大值,然后在那里种子标签。后者是首选,因此我可以保留一个按标签索引的数组,以存储所有区域的x、y、z、t最小/最大范围(也可以作为后处理)。如果某个区域未扩展到最新的时间片,则会从数据中删除该区域,并将其位置写入数据库。如果尾随时间片已以这种方式完全释放(总和为零),请将其从内存中删除。(或者,如果内存溢出,也要删除最新的;这样做的近似值将不得不忍受)

看来这应该行得通。考虑到z维度的有限大小,您认为启动x、y、z线程块还是启动x、y线程块并让每个线程在z维度上循环更好?这是一种“试一试”的做法,还是有一个简单的答案

我刚刚想到的另一个优化;如果我将一块x,y,z加载到共享内存中,在我得到内存的同时执行几次泛洪填充更新不是更快吗?也许最好让本地内存迭代收敛,然后继续。。。我想这与上述问题有关。单个邻居最大查找可能是次优计算强度,因此在z上循环或多次迭代都会抵消这一点。我想我更喜欢后者

另一个问题;看起来像这样的东西还不存在,但是链接到包含做类似事情的模板代码的项目(优化的3d泛洪填充代码?),我的CUDA知识仍然是零碎的


提前感谢您的想法和反馈

最简单的方法是使用1D存储并在其上覆盖4D索引模式

地址=x+y*宽度+z*高度*宽度+t*长度*高度*宽度

这意味着

数据(0,0,0,0)和数据(1,0,0,0)位于连续地址,但

数据(0,0,0,0)和数据(0,0,0,1)是宽度*高度*长度部分的地址

但是,如果您的访问模式正在处理最近邻,那么您需要空间位置来编制索引

这可以通过对索引进行Morton Z(Peano键)排序来实现。它将最近邻放在紧密的线性内存地址中。该Z阶线性地址是通过交错x、y、Z、t索引的交替位获得的。有关二维示例,请参见


最简单的方法是使用1D存储并在其上覆盖4D索引模式

地址=x+y*宽度+z*高度*宽度+t*长度*高度*宽度

这意味着

数据(0,0,0,0)和数据(1,0,0,0)位于连续地址,但

数据(0,0,0,0)和数据(0,0,0,1)是宽度*高度*长度部分的地址

但是,如果您的访问模式正在处理最近邻,那么您需要空间位置来编制索引

这可以通过对索引进行Morton Z(Peano键)排序来实现。它将最近邻放在紧密的线性内存地址中。该Z阶线性地址是通过交错x、y、Z、t索引的交替位获得的。有关二维示例,请参见


我建议使用金字塔处理方案:您可以快速计算类似mipmap的细节级别,其中存储组合体素的最大/最小值。这将产生类似于八叉树的结果。然后,您可以只在感兴趣的区域开始分割,这将提供相当大的加速。如果您只有很少且非常小的片段,那么这应该可以很好地工作

我想你也可以使用级别集(可以在GPU上实现),但我发现这些级别集的实现有点困难(谷歌的“CUDA级别集”)


您是否需要随着时间的推移跟踪您的细分市场?你知道怎么做吗?

我建议一种金字塔处理方案:你可以快速计算类似mipmap的细节级别,在那里你可以存储组合体素的最大/最小值。这将产生类似于八叉树的结果。然后,您可以只在感兴趣的区域开始分割,这将提供相当大的加速。如果您只有很少且非常小的片段,那么这应该可以很好地工作

我想你也可以使用级别集(可以在GPU上实现),但我发现这些级别集的实现有点困难(谷歌的“CUDA级别集”)


您是否需要随着时间的推移跟踪您的细分市场?你知道怎么做吗;我找到了一个我满意的工作方案;可能会在更成熟的时候把它放到网上的某个地方。以下是描述: