我正在学习在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或者finish返回的错误给了我CL_SUCCESS ..所以,或者这不应该因为某些原因给我错误或者我不知道如何得到它们。答案是什么?< / p>
答案 0 :(得分:2)
与在C和C ++中一样,在OpenCL中超出数组范围是未定义的行为,因此它不一定会引发错误条件,但几乎可以引起任何类型的错误奇怪的行为。因此,不要依靠运行时来捕获这种编程错误。您的程序更有可能崩溃,甚至整个系统都会因此类错误而崩溃(如果它没有使用IOMMU),而不是返回值中的错误代码
作为一个实现细节,您很可能会发现缓冲区以4096字节为增量映射到GPU的内存空间 - 一页内存。因此,如果您的越界访问仍然在有效的4096字节页面内,那么它更可能表现得像典型的基于CPU的缓冲区溢出。