我有一个 3D 数据,存储在一维数组中。我这样计算一维索引:
index = i + j * WIDTH + k * WIDTH * HEIGHT
我需要从 index
中获取原始的 i,j,k
索引。显而易见的方法是这样的:
k = index / (WIDTH * HEIGHT)
j = (index % (WIDTH * HEIGHT)) / WIDTH
i = index - j * WIDTH - k * WIDTH * HEIGHT
但我想知道,是否有更有效的方法来做到这一点?至少没有模...
这个问题的上下文 - 我在 CUDA 中有一个内核,我可以在其中访问数据并计算 i, j, k
索引(index
对应于唯一的线程 ID) .那么也许有一些特定于 CUDA 的方法可以做到这一点?我想这是一个很常见的问题,但我找不到更好的方法...
感谢您的想法!
最佳答案
你得到的很好;如果你想避免模数(因为这在 gpus 上非常昂贵)你可以用 j
做你用 i
做的事情:
j = (index - (k*WIDTH*HEIGHT))/WIDTH
如果你想让逻辑更清晰一点,又不需要原来的index
,可以这样做
k = index/(WIDTH*HEIGHT);
index -= k*WIDTH*HEIGHT;
j = index/WIDTH;
index -= j*WIDTH;
i = index/1;
然后可以非常直接地扩展到任意维度。您可以尝试通过预先计算 WIDTH*HEIGHT
等方式来调整上述内容,但我只是打开优化并相信编译器会为您执行此操作。
关于四舍五入到 2 的幂的建议是正确的,因为它会加快索引计算,但代价相当大。在这种(不算太糟糕)的情况下,WIDTH=HEIGHT=100
,它会使 3d 数组的内存需求增加 60% (WIDTH=HEIGHT=128
) 和内存GPU 上通常已经很紧张;并根据您的访问模式,使您的数组大小为 2 的幂可能会引入存储区冲突问题。
关于c++ - 从 1D 数组表示计算 3D 索引的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13894028/