我正在用C ++和OpenCL开发这个测试应用程序,但我无法弄清楚为什么我会遇到这个非常奇怪的问题,这会进一步导致分段错误。
部分代码:
output = new cl_float[TestCount*TrainCount]; // output array
output_buf = new cl::Buffer(*context, CL_MEM_WRITE_ONLY, sizeof(cl_float)*TestCount*TrainCount, NULL);
// .... some more stuff
queue->enqueueReadBuffer(*output_buf, CL_TRUE, 0, TestCount*TrainCount, output);
这里,output和output_buf是指向各自数据的指针。
当我尝试在处理完所有内容后访问输出数组的任何元素时发生seg-fault。经过进一步调试,我发现它存储的最大元素数是562,而它应该是2250(TestCount = 150,TrainCount = 15)。此外,令人惊讶的是,我可以从GDB访问任何元素,但不能向上访问562。
我毫不怀疑代码中没有错误,我绝对相信所有2250输出都是由GPU处理的。这是通过在每个线程中以原子方式递增输出数组的第一个元素然后通过GDB输出来进行测试。
似乎我已经排除了很多可能性,但对于它,我仍然无法弄清楚是什么导致了这个问题。堆很少有机会被填满,但是我发现我的应用程序只使用了37M的内存。
任何帮助将不胜感激!
更新:詹姆斯是对的。这是因为没有从内存中读取足够的字节。 seg-fault的回溯如下 -
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000000000000c
0x0000000100002402 in main (argc=4, argv=0x7fff5fbffb88)
at TestApplication.cpp:202
202 cout << OpenCL_KNN::output[0] << " " << OpenCL_KNN::output[1] << " " << OpenCL_KNN::output[2] << " " << OpenCL_KNN::output[3];
正在访问的4个索引是明确定义的。在此之前没有任何内容给我任何错误。除了我之前提到的以外,输出数组不会被改变/创建。
更新2 :错误已解决。它只发生在Mac OS X中。它有一些东西要做我访问输出的方式。一旦我在OpenCL_KNN命名空间中创建了一个函数,将输出返回给我,它就能很好地工作。
答案 0 :(得分:2)
我不熟悉CL的C ++包装器,但我猜测TestCount*TrainCount
是sizeof(cl_float)
因子太少而无法从GPU读回的因素。你的代码应该是:
queue->enqueueReadBuffer(*output_buf, CL_TRUE, 0, sizeof(cl_float)*TestCount*TrainCount, output);
然而,这并不能解释您的段错误。也许你在其他地方也犯了同样的错误?
答案 1 :(得分:0)
发生此错误是因为您正在访问未初始化或被删除的内存。 错误出现在这行代码中。
queue->enqueueReadBuffer(*output_buf, CL_TRUE, 0, TestCount*TrainCount, output);
检查代码中的每个对象和可变量(指针)是否都已正确初始化。一旦完成,此错误将消失。没有必要在指定的代码行上生成错误,它可以发生在位置您访问未初始化的内存地址的地方。