2012-01-27 54 views
4

有没有办法阻止OpenCL内核执行? 例如,我进入内核,做一些计算,然后停止它,如果某些条件得到满足,否则,我等待它完成:有没有办法阻止OpenCL内核执行?

clEnqueueNDRange(queue, ...); // start kernel function 

// do other stuff... 
// ... 

if (some condition met) { 
    stopKernel(); 
} else { 
    clFinish(queue); 
} 

谢谢大家帮忙

回答

7

号一旦你已经入队了你的内核,它会运行完成。

之一来完成东西像上面的方法是做到这一点:

while (data_left_to_process) { 

    clEnqueueNDRangeKernel(..., NDRange for a portion of the data, ...) 

    // other work 

    if (condition) { 
     break; 
    } 

    // adjust NDRange for next execution to processes the next part of your data 

} 

clFinish(queue); 

这可以让你避免处理所有的数据,具有明显的权衡,你现在在更小的块提交工作,这可能会对性能产生影响。

2

可能。

  1. 在上下文中创建两个命令队列。
  2. 创建两个内核,一个执行工作,另一个执行中止。每个内核都可以访问共享的全局缓冲区。
  3. 将第一个内核加载到队列1中。
  4. 当您想暂停执行时,将第二个内核加载到队列2中。

或者,您可以使用无序队列并将第二个内核加载到同一个命令队列中以暂停执行。你必须小心一些(必要时使用clFinish/clFlush),但这是更自然的做法。

(多队列)的一些伪代码:

clEnqueueNDRange(queue1, kernel1, ...); //start work kernel 
// do other stuff 
// ... 
if (condition) 
    clEnqueueNDRange(queue2, kernel2, ...); //stop work kernel 
clFinish(queue1); 
clFinish(queue2); // entirely unnecessary if using in-order queues 

使用INT缓冲区或浮动作为您停止变量,并通过您的内核中的global_id访问它们,以减少内的全球阅读成本循环。缺点是你的状态是不确定的:没有进一步的变量来计算执行等,你不知道有多少工作项目和哪些已经被执行。

而且内核:

void kernel1(... ,global int * g_stop) 
{ 
    int index_from_ids = ...; 
    while (g_stop[index_from_ids] == 0) // or 'if' for single pass execution 
    { 
     // do work here 
    } 
} 

void kernel2(... ,global int * g_stop) 
{ 
    int index_from_ids = ...; 
    g_stop[index_from_ids] = 1; 
} 
+0

有没有一种方法,使该解决方案100%定义的行为,比如用原子INT? – galinette 2018-02-16 10:10:20

相关问题