假设我们有 2^10 个 CUDA 核心和 2^20 个数据点。我想要一个能够处理这些点并为每个点提供真/假的内核。所以我会有 2^20 位。示例:
bool f(x) { return x % 2? true : false; }
void kernel(int* input, byte* output)
{
tidx = thread.x ...
output[tidx] = f(input[tidx]);
...or...
sharedarr[tidx] = f(input[tidx]);
sync()
output[blockidx] = reduce(sharedarr);
...or...
atomic_result |= f(input[tidx]) << tidx;
sync(..)
output[blckidx] = atomic_result;
}
Thrust/CUDA 有一些算法,如“分区”、“转换”,它们提供了类似的替代方案。
我的问题是,当我使用提供相应 bool 结果的谓词编写相关的 CUDA 内核时,
我应该为每个结果使用一个字节并将结果直接存储在输出数组中吗?执行一个步骤进行计算,稍后执行另一步骤进行归约/分区。
我是否应该压缩共享内存中的输出,使用 8 个线程使用一个字节,然后最后将共享内存中的结果写入输出数组?
我应该使用原子变量吗?
编写这样的内核和保存结果的最符合逻辑的数据结构的最佳方法是什么?使用更多内存并简单地对主内存进行更多写入,而不是在写回结果内存区域之前尝试处理压缩结果,是否更好?
最佳答案
使用efficiently pack the results固有的__ballot()
扭曲投票时,速度和数据大小之间没有权衡.
假设您可以将输出
重新定义为uint32_t类型,并且您的 block 大小是扭曲大小(32)的倍数,您可以简单地使用存储打包输出
output[tidx / warpSize] = __ballot(f(input[tidx]));
请注意,这会使 warp 的所有线程尝试存储 __ballot()
的结果。经线中只有一个线程会成功,但由于它们的结果都是相同的,所以哪一个成功并不重要。
关于c++ - 如何存储 CUDA 内核函数的 bool 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41310024/