这是否应该给出错误,如果是,如何检查它?(OpenCL)

Should this give an error, and if yes, how to check it? (OpenCL)

本文关键字:OpenCL 何检查 检查 是否 出错 如果 错误      更新时间:2023-10-16

我正在学习在 OpenCL 中制作健壮的代码,并面对以下内核代码:

string kernel_code =
" void kernel simple_add(global const int *A,    "
"                        global const int *B,    "
"                        global int *C, int n) { "
"                                                "
"   int index = get_global_id(0);                "
"   C[index]=A[index]+B[index];                  "
" }                                              ";

并故意使用以下代码将其发送到 GPU:

Kernel ker(program, "simple_add");
ker.setArg(0, buffer_A);
ker.setArg(1, buffer_B);
ker.setArg(2, buffer_C);
ker.setArg(3, N);
q.enqueueNDRangeKernel(ker,NullRange,NDRange(32),NDRange(32));
q.finish();
问题是,我

使用的工作项比需要的多,所以我认为我应该检查索引是否超出内核代码的范围。但我没有使用它,并且检查由 enqueueNDRangeKernel 或完成返回的错误给了我CL_SUCCESS。所以,或者由于某种原因这不应该给我错误,或者我不知道如何获得它们。答案是什么?

与 C 和 C++ 一样,在 OpenCL 中,数组中的越界是未定义的行为,因此它不一定会引发错误条件,但会导致几乎任何类型的奇怪行为。因此,不要依赖运行时来捕获此类编程错误。由于这种错误,而不是返回值中的错误代码,您的程序更有可能崩溃,甚至整个系统都会崩溃(如果它不使用 IOMMU)。

作为实现细节,您很可能会发现缓冲区以 4096 字节为增量映射到 GPU 的内存空间 - 一页内存。因此,如果您的越界访问仍在有效的 4096 字节页面中,则它的行为更有可能类似于典型的基于 CPU 的缓冲区溢出。