c++ - 从 1D 数组表示计算 3D 索引的有效方法

标签 c++ math cuda

我有一个 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/

相关文章:

c++ - 在 CUDA 中共享内存? CODE 是如何工作的?

c++ - boost::asio::streambuf::consume - 注入(inject)垃圾字符

android - 用地理坐标(纬度、经度)计算物体的方向

java - 缩放和旋转点数组

c++ - 在我的运行时cuda程序中,cpu和gpu可以异步计算,但不能协同计算,为什么?

c++ - CUDA 中的全局内存和纹理有什么区别?

c++ - union 中的 std::shared_ptr

C++:将 WCHAR 转换为 LPCWSTR - 实际工作示例

c++ - 有条件地替换字符串中的正则表达式匹配

algorithm - 在程序中取对数会对计算机造成负担吗?