1

好吧,我试过在苹果开发者论坛上提问,但没有人回应。我认为stackoverflow会更合适。这里是...

我有一些 OpenCL 内核,它遍历存储在帧缓冲区对象中的像素,并计算非黑色和非白色像素。它曾经在我的机器上运行良好,但我相信 Mac OS X 和/或 devtools 的更新可能会导致问题导致它停止。

与内核代码关联的内核对象附加到 QT 窗口,当窗口需要渲染更新时,内核代码会运行 n 次。此窗口在初始创建后会更新两次,这意味着 openCL 代码的序列最初不会引起问题。当我将窗口置于前台时,它需要再次更新并尝试再次运行内核代码 n 次。但在这些 n 次中间,它停止了。即,如果它需要运行 51 次,它会在迭代 26 处停止。看来对 clEnqueueReadBuffer 的调用会导致停止。

除非绝对必要,否则我将省略有关为什么使用 openCL 代码的详细信息,因为这可能会使人们感到困惑。我认为专注于 OpenCL 代码本身会很好。这里供参考:http ://dl.dropbox.com/u/10838242/forumsquestion.cpp

这是 gdb 回溯:

#0  0x00007fff8e3a6122 in __psynch_mutexwait ()
#1  0x00007fff8955ad9d in pthread_mutex_lock ()
#2  0x000000010dd3acbd in gldFlushQueue ()
#3  0x000000010bbc193f in IOAccelContextFinishResourceSysMem ()    
#4  0x000000010bbcd5b0 in gpumAcquireFenceOnQueue ()
#5  0x000000010dd43fcd in gldCopyBufferDataWithQueue ()
#6  0x00007fff8ffa7e2e in GCC_except_table49 ()
#7  0x00007fff8ffc5f11 in clFinish ()
#8  0x00007fff936800b6 in _dispatch_client_callout ()
#9  0x00007fff93681723 in _dispatch_barrier_sync_f_invoke ()
#10 0x00007fff8ffc5ddb in clFinish ()
#11 0x00007fff8ffc25c2 in clSetEventCallback ()
#12 0x00007fff8ffb86e6 in clEnqueueReadBuffer ()
#13 0x0000000100020a31 in CLHandler::update (this=0x107683e20, tagged=@0x7fff5fbfb960, w=761, h=711) at clhandler.cpp:343
#14 0x000000010002f8c1 in CustomBladesGLWidget::render (this=0x1072b09e0, indexMode=true, offset=135288, numPnts=4416, blobID=25, bladeIdsIntersected=@0x7fff5fbfb960) at customBladesGLWidget.cpp:943

在附件中,第 343 行(上面的粗体)对应于这个调用(在函数 CLHandler::update 中):

//read data from buffer
status = clEnqueueReadBuffer(cqueue,hitbuffer,CL_TRUE,0,mNumBladeCells * sizeof(float),mBladesHit,0, NULL,&event);
handleError("clEnqueueReadBuffer","",status);

现在,如果我要在对 clEnqueueWriteBuffer 的初始调用下方注释所有内容,它将改为在该函数调用处停止。我不知道为什么会这样。这不像我正在尝试使用互斥锁或任何东西。任何帮助是极大的赞赏。

系统规格:MacbookPro 8,2、Core i7 2.2 GHz、AMD Radeon HD 6750M、OS X 10.8.2。

谢谢

4

2 回答 2

1

glFinish在使用 GL 对象的第一个 OpenCL API 调用之前应该有一个调用,clFinish在最后一个之后应该有一个调用。较弱的选项(即调用 Flush 而不是 Finish)可能适用于特定平台。

请参阅OpenCL 1.2 扩展规范,第 9.7.6.1 节。

更新。 具体来说,在 Apple 平台上,最快的选择是glFlushRenderApple在第一个 OpenCL 调用之前和clFinish最后一个之后调用。

于 2013-01-05T02:46:03.090 回答
0

如果您声明它正在阻止写入(第三个参数为真),为什么要将事件传递给clEnqueueWriteBuffer/clEnqueueReadBuffer ?由于这个原因,您也不需要对clWaitForEvents(1, &event)进行任何调用。

相反,我会将事件添加到clEnqueueNDRangeKernel并在clFlush()之后等待它。因为clFlush仅触发执行,但不能保证在其调用之后所有先前排队的命令都将完成(与clFinish不同)。然后才调用clEnqueueReleaseGLObjects。但是,只要您的队列不是使用CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE标志创建的,您的情况也应该没问题。

您还可以指定哪些确切的行被注释/取消注释吗?

于 2013-01-04T22:52:41.053 回答