可能。
- 在上下文中创建两个命令队列。
- 创建两个内核,一个执行工作,另一个执行中止。每个内核都可以访问共享的全局缓冲区。
- 将第一个内核加载到队列1中。
- 当您想暂停执行时,将第二个内核加载到队列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;
}
有没有一种方法,使该解决方案100%定义的行为,比如用原子INT? – galinette 2018-02-16 10:10:20