我正在使用OpenCL实现一个算法。我将多次循环使用C ++并每次调用相同的OpenCL内核。内核将生成下一次迭代的输入数据和这些数据的数量。目前,我在每个循环中读回这个数字两个用法:
我发现读数占用了循环的大部分时间。有什么方法可以避免吗?
一般来说,如果需要重复调用内核,并且退出条件依赖于内核生成的结果(不是固定数字循环),那么如何有效地执行呢?有没有像OpenGL中的遮挡查询那样你可以做一些查询而不是从GPU回读?
答案 0 :(得分:2)
从GPU内核读回一个数字总是需要10s - 1000s微秒或更长时间。
如果控制号始终在减少,您可以保留在全局内存中,并根据全局ID对其进行测试,并确定内核是否在每次迭代时都有效。使用全局内存屏障来同步所有线程...
kernel void x(global int * the_number, constant int max_iterations, ... )
{
int index = get_global_id(0);
int count = 0; // stops an infinite loop
while( index < the_number[0] && count < max_iterations )
{
count++;
// loop code follows
....
// Use one thread decide what to do next
if ( index == 0 )
{
the_number[0] = ... next value
}
barrier( CLK_GLOBAL_MEM_FENCE ); // Barrier to sync threads
}
}
答案 1 :(得分:1)
你有几个选择:
这两个选项都允许您跳过回读。
答案 2 :(得分:0)
我刚刚完成一些研究,我们必须解决这个问题!
我们发现了一些事情:
使用两个(或更多)缓冲区!进行内核的第一次迭代 对b1中的数据进行操作,然后对b2进行操作,然后再对b1进行操作。在 在每次内核调用之间,读回另一个缓冲区的结果 并检查是否是时候停止迭代了。当内核花费的时间超过读取时,效果最佳。使用分析工具确保您不等待读取(如果是,请增加缓冲区数量)。
过度拍摄!为每个内核添加一个完成检查,然后调用它 在复制数据之前几次(100s)次。如果你的内核是 低成本,这可以很好地工作。