HOST在CPU设备结束之前的不完整任务

时间:2016-03-03 10:02:53

标签: events opencl cpu blocking

我只有一个带有两个内核的CPU Core i3,所以我只能使用CPU而不是GPU。我想测试一个简单的例子,使用OpenCL和一个简单的添加内核。但这是我的问题:

在分配平台,CPU设备等之后,我执行以下操作:

1)clEnqueueNDRange()将内核任务排入队列,并使用最后一个参数为此任务的完成分配一个事件。

2)使用CL_COMPLETE的clSetEventCallback()将回调函数链接到上述事件。

通常,任务完成时应调用回调函数。但它并没有。的确,在结束事件中INCOMPLETE的任务如果主持人在结束之前要做很多事情。有人能说我为什么吗?

这是我的最小代码:

/** Simple add kernel */
private static String programSource0 =
    "__kernel void vectorAdd(" +
    "     __global const float *a,"+
    "     __global const float *b, " +
    "     __global float *c)"+
    "{"+
    "    int gid = get_global_id(0);"+
    "    c[gid] = a[gid]+b[gid];"+
    "}";

/** The entry point of this sample */
public static void main(String args[])
{
    /** Callback function */
    EventCallbackFunction kernelCommandEvent = new EventCallbackFunction()
    {
        @Override
        public void function(cl_event event, int event_status, Object user_data)
        {
            System.out.println("Callback: task COMPLETED");
        }
    };

    // Initialize the input data
    int n = 1000000;
    float srcArrayA[] = new float[n];
    float srcArrayB[] = new float[n];
    float dstArray0[] = new float[n];
    Array.fill(srcArrayA, 1,0f);
    Array.fill(srcArrayB, 1,0f);

    // .
    // (hidden) Allocation of my Intel platform, CPU device, kernel, commandQueue, and memory buffer, set the argument to kernel etc...
    // .


    // Set work-item dimensions and execute the kernels
    long globalWorkSize[] = new long[]{n};

    // I pass an event on completion of the command queue.        
    cl_event[] myEventID = new cl_event[1];
    myEventID[0] = new cl_event();
    clEnqueueNDRangeKernel(commandQueue, kernel0, 1, null, globalWorkSize, null, 0, null, myEventID[0]);

    // I link the event to the callback function "kernelCommandEvent", and pass 10 as parameter
    clSetEventCallback(myEventID[0], CL_COMPLETE, kernelCommandEvent, new Integer(10));


    // host does some very long stuff !!

    // Normally, my device task should be completed
    int[] ok = new int[1];
    Arrays.fill(ok, 0);
    clGetEventInfo(myEventID[0], CL_EVENT_COMMAND_EXECUTION_STATUS, Sizeof.cl_int, Pointer.to(ok), null);
    if (ok[0] == CL_COMPLETE) System.out.println("Task COMPLETE");else System.out.println("Task INCOMPLETE");
}

1 个答案:

答案 0 :(得分:1)

Enqueue不会强制执行任务。它只是把它放在队列中。

只有在您执行以下任务时才会执行:

  • 使用clFlush()强制立即执行。
  • 进行直接或间接依赖该任务的阻止呼叫。

有些司机也可以决定即使你没有冲洗它们也会开始处理任务。但这是依赖于实现的。如果您想确保使用clFlush(commandQueue);

额外: 这种行为就是这样,因为将数据排队到设备的开销可能很大,如果在循环中多次调用它,那么每次Enqueue调用都可能无效。相反,它被称为刷新或阻塞调用,因此可以进行批处理。