我正在学习在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]; "
" } ";
Run Code Online (Sandbox Code Playgroud)
并故意使用以下代码将其发送到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();
Run Code Online (Sandbox Code Playgroud)
问题是,我使用的工作项超过了需要的工作,因此,我认为我应该检查索引是否超出内核代码的范围。但是我没有使用它,检查enqueueNDRangeKernel或完成返回的错误使我得到CL_SUCCESS。
与 C 和 C++ 中一样,数组越界是未定义的行为,因此它不一定会引发错误情况,但可能会导致几乎任何类型的奇怪行为。因此,不要依赖运行时来捕获此类编程错误。由于此类错误,而不是返回值中的错误代码,您的程序更有可能崩溃,甚至整个系统崩溃(如果不使用 IOMMU)。
作为实现细节,您很可能会发现缓冲区以 4096 字节增量(一页内存)映射到 GPU 的内存空间。因此,如果越界访问仍在有效的 4096 字节页面内,则其行为很可能类似于典型的基于 CPU 的缓冲区溢出。