假设多个工作项想要附加到全局堆栈:
void kernel(__global int* stack) {
... do stuff ...
push(stack, value);
... do stuff ...
return y;
}
在内核运行之后,stack
包含推送到它的每个value
是可取的。订单无关紧要。在OpenCL 1.2中执行此操作的正确方法是什么?
一个明显的想法是使用atomic_inc
来获取长度并写入:
void push(__global int* stack, int val) {
int idx = atomic_inc(stack) + 1; // first element is the stack length
stack[idx] = val;
}
但我推测所有工作项都会在同一个内存位置分别调用atomic_inc
,这会破坏并行性。另一个想法是只写一个大于工作项数的临时数组:
void push(__global int* stack, int val) {
stack[get_global_id(0)] = val;
}
这给我们留下了稀疏的数值:
[0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 9, 0, 0, ...]
然后可以使用"stream compaction"来压缩。因此,我想知道这些想法中哪些是最有效的,如果可能还有第三种选择我不知道。
答案 0 :(得分:2)
我无法在这里给你一个明确的答案,但我可以提出一些建议 - 如果你有资源,尝试实施不止一个,并分析他们在所有不同的表现您计划部署的OpenCL实施类型。您可能会发现不同的解决方案在不同的硬件/软件上的表现不同。
可能有其他选择,但那些应该给你一些想法。