Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCL(意外地)在尝试运行内核代码时冻结_C++_Macos_Opencl - Fatal编程技术网

C++ OpenCL(意外地)在尝试运行内核代码时冻结

C++ OpenCL(意外地)在尝试运行内核代码时冻结,c++,macos,opencl,C++,Macos,Opencl,嗯,我试着在苹果开发者论坛上提问,但没有人回应。我认为stackoverflow更合适。这是 我有一些OpenCL内核,它运行于存储在帧缓冲区对象中的像素,并计算非黑色和非白色像素。它过去在我的机器上运行得很好,但我相信对MacOSX和/或devtools的更新可能导致了一个问题,导致它暂停 与内核代码关联的内核对象附加到QT窗口,当窗口需要渲染更新时,内核代码运行n次。此窗口在最初创建后会更新两次,这意味着openCL代码序列最初不会导致问题。当我将窗口置于前台时,它需要另一次更新,并尝试再次

嗯,我试着在苹果开发者论坛上提问,但没有人回应。我认为stackoverflow更合适。这是

我有一些OpenCL内核,它运行于存储在帧缓冲区对象中的像素,并计算非黑色和非白色像素。它过去在我的机器上运行得很好,但我相信对MacOSX和/或devtools的更新可能导致了一个问题,导致它暂停

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

我将省略关于为什么使用openCL代码的细节,除非这是绝对必要的,因为这可能会让人困惑。我认为专注于OpenCL代码本身会很好。以下为参考:

以下是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中):

现在,如果我在对clEnqueueWriteBuffer的初始调用下面注释所有内容,它将在该函数调用处暂停。我不知道为什么会这样。我并不是在尝试使用互斥或其他什么。非常感谢您的帮助

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


谢谢

如果您声明事件正在阻止写入(第三个参数为true),为什么要将事件传递给clEnqueueWriteBuffer/clEnqueueReadBuffer?因此,您也不需要调用clWaitForEvents(1,&event)

相反,我会将事件添加到clEnqueueNDRangeKernel。然后在clFlush()之后等待它。 因为clFlush只触发执行,但不保证调用后所有先前排队的命令都将完成(与clFinish不同)。然后才调用ClenqueureReleaseGlobalObjects。但您的情况也应该是正常的,只要您的队列不是使用CL\u queue\u OUT\u OF\u ORDER\u EXEC\u MODE\u ENABLE标志创建的


还可以指定哪些行被注释/未注释?

如果您声明它正在阻止写入(第三个参数为true),为什么要将事件传递给clEnqueueWriteBuffer/clEnqueueReadBuffer?因此,您也不需要调用clWaitForEvents(1,&event)

相反,我会将事件添加到clEnqueueNDRangeKernel。然后在clFlush()之后等待它。 因为clFlush只触发执行,但不保证调用后所有先前排队的命令都将完成(与clFinish不同)。然后才调用ClenqueureReleaseGlobalObjects。但您的情况也应该是正常的,只要您的队列不是使用CL\u queue\u OUT\u OF\u ORDER\u EXEC\u MODE\u ENABLE标志创建的


还可以指定哪些行被注释/未注释?

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

见第9.7.6.1节


更新。特别是在Apple平台上,最快的选择是在第一次OpenCL调用之前调用
glFlushRenderApple
,在最后一次调用之后调用
clFinish

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

见第9.7.6.1节


更新。特别是在苹果平台上,最快的选择是在第一次调用OpenCL之前调用
glFlushRenderApple
,在最后一次调用之后调用
clFinish

谢谢。我已经在链接的cpp文件中标记了注释内容的位置(请参阅update(*)函数)。我会给你一些与活动相关的建议。我使用它进行clEnqueueWrite/Read调用,因为我是OpenCL的新手……是的,clWaitForEvents是不需要的,因为它已经被阻塞了。所以你想让我在NDRangeKernel之后等待事件,然后调用release?虽然waitforevents调用可以在clenqueuendrangekernel之后进行,并且不会导致锁定,但它应该在调用释放对象之后,根据@Eric链接的规范。无论如何,根据这个链接,确保挂起的OpenGL和/或OpenCL操作不会相互干扰是一个很好的实践。这很重要,因为我的代码确实使用OpenGL对象。我在forumsquestion.cpp文件中添加了更新函数的“好版本”,就在“坏版本”之后。谢谢。我已经在链接的cpp文件中标记了注释内容的位置(请参阅update(*)函数)。我会给你一些与活动相关的建议。我使用它进行clEnqueueWrite/Read调用,因为我是OpenCL的新手……是的,clWaitForEvents是不需要的,因为它已经被阻塞了。所以你想让我在NDRangeKernel之后等待事件,然后调用release?虽然waitforevents调用可以在clenqueuendrangekernel之后进行,并且不会导致锁定,但它应该在调用释放对象之后,根据@Eric链接的规范。无论如何,根据这个链接,这是一个很好的公关
//read data from buffer
status = clEnqueueReadBuffer(cqueue,hitbuffer,CL_TRUE,0,mNumBladeCells * sizeof(float),mBladesHit,0, NULL,&event);
handleError("clEnqueueReadBuffer","",status);