我有一个2M +点的数组(计划在适当的时候增加到20M),我正在通过OpenCL运行计算。我想删除任意位于随机三角形几何体内的点。
如何在OpenCL内核进程中执行此操作?
我已经可以:
识别那些落在三角形之外的点(内核中poly算法的简单点)
将其坐标传递给全局输出数组。
但是:
openCL全局输出数组不能变量,所以我初始化它以匹配大小方面的输入点数
因此,当一个点落在三角形内时,最终输出会出现0,0分
因此,输出数组本身不会导致任何减少。
可以在openCL上下文中删除0,0点吗?
n.b。我在OpenFrameworks中编码,因此c ++实现链接到.cl文件
答案 0 :(得分:1)
如果我理解你的问题,你可以这样做:
- >在内核中,您可以识别三角形中的点,并且:
if(element[idx]!=(0,0))
output_array[atomic_inc(number_of_elems)] = element[idx];
最后,在您将拥有的主机中的output_array的第一个number_of_elems中 你的内心点。
我希望这能帮到你, 最好
答案 1 :(得分:1)
只是大多数点落入原子条件的情况下的替代方案:
可以有本地计数器和本地原子。然后,要将该原子合并到全局值,可以使用atomic_add()
。女巫将返回“之前”的全球价值。因此,您只需将索引复制到该地址即可。
它应该是一个明显的加速,因为线程将在本地同步,并且只在全局同步一次。全局副本可以是并行的,因为地址永远不会重叠。
例如:
__kernel mykernel(__global MyType * global_out, __global int * global_count, _global MyType * global_in){
int lid = get_local_id(0);
int lws = get_local_size(0);
int idx = get_global_id(0);
__local int local_count;
__local int global_val;
//I am using a local container, but a local array of pointers to global is possible as well
__local MyType local_out[WG_SIZE]; //Ensure this is higher than your work_group size
if(lid==0){
local_count = 0; global_val = -1;
}
barrier(CLK_LOCAL_MEM_FENCE);
//Classify them
if(global_in[idx] == ....)
local_out[atomic_inc(local_count)] = global_in[idx];
barrier(CLK_LOCAL_MEM_FENCE);
//If not, we are done
if(local_count > 0){
//Only the first local ID does the atomic to global
if(lid == 0)
global_val = atomic_add(global_count,local_count);
//Resync all the local workers here
barrier(CLK_LOCAL_MEM_FENCE);
//Copy all the data
for(int i=0; i<local_count; i+=lws)
global_out[global_val+i] = local_out[i];
}
}
注意:我没有编译它,但应该或多或少地工作。
答案 2 :(得分:0)
根据数据的外观,有一些替代方案,无论是好还是坏。我在下面放了一个。
删除已识别的点也可以通过在每个工作组的单独数组中注册它们来实现 - 您需要使用与Moises的答案相同的atomic_inc(请参阅我在那里关于在工作组级别执行此操作的说法! )。最终结果是不需要删除的部分的起点和终点列表。然后,您可以通过不同的线程复制数组的部分内容。如果您有需要删除的点集群,则效果较差