我正在开发一个使用 OpenCL 的应用程序,针对 1.2 版本。我使用 DX11 互操作性来显示内核结果。我在 Intel (iGPU) 和 Nvidia 平台上尝试我的代码,在这两个平台上我都发现了相同的行为。
我对 clEnqueueNDRangeKernel 的调用阻塞了 CPU 线程。我检查了文档,但找不到声明内核调用可能阻塞的情况。我在一些论坛上读到,这些事情有时会在某些 OpenCL 实现中发生。该代码工作正常并输出有效结果。API 在任何给定点都不会返回任何错误,一切看起来都很顺利。
我无法粘贴完整的源代码,但我会粘贴循环部分:
size_t local = 64;
size_t global = ctx->dec_in_host->horizontal_blocks * ctx->dec_in_host->vertical_blocks * local;
print_if_error(clEnqueueWriteBuffer(ctx->queue, ctx->blocks_gpu, CL_TRUE, 0, sizeof(block_input) * TOTAL_BLOCKS, ctx->blocks_host, 0, NULL, &ctx->blocks_copy_status), "copying data");
print_if_error(clEnqueueWriteBuffer(ctx->queue, ctx->dec_in_gpu, CL_TRUE, 0, sizeof(decoder_input), ctx->dec_in_host, 0, NULL, &ctx->frame_copy_status), "copying data");
if (ctx->mode == nv_d3d11_sharing)
print_if_error(ctx->fp_clEnqueueAcquireD3D11ObjectsNV(ctx->queue, 1, &(ctx->image_gpu), 0, NULL, NULL), "Adquring texture");
else if (ctx->mode == khr_d3d11_sharing)
print_if_error(ctx->fp_clEnqueueAcquireD3D11ObjectsKHR(ctx->queue, 1, &(ctx->image_gpu), 0, NULL, NULL), "Adquring texture");
t1 = clock();
print_if_error(clEnqueueNDRangeKernel(ctx->queue, ctx->kernel, 1, NULL, &global, &local, 0, NULL, &ctx->kernel_status), "kernel launch");
t2 = clock();
if (ctx->mode == nv_d3d11_sharing)
print_if_error(ctx->fp_clEnqueueReleaseD3D11ObjectsNV(ctx->queue, 1, &(ctx->image_gpu), 0, NULL, NULL), "Releasing texture");
else if (ctx->mode == khr_d3d11_sharing)
print_if_error(ctx->fp_clEnqueueReleaseD3D11ObjectsKHR(ctx->queue, 1, &(ctx->image_gpu), 0, NULL, NULL), "Releasing texture");
printf("Elapsed time %lf ms\n", (double)(t2 - t1)*1000 / CLOCKS_PER_SEC);
所以我的问题是:
- ¿ 你知道 clEnqueueNDRangeKernel 会阻塞的任何原因吗?
- ¿ 您知道 Dx11 互操作是否会导致此问题?
- ¿ 你知道某些 OpenCL 配置是否可以创建同步内核启动吗?
谢谢 :)
编辑1:感谢doqtor评论,我意识到注释掉内核的部分内核启动变得异步。结果不好,但我有一些提示可以找出答案。