我很迷茫,但是幸运的是我将问题缩小到几行代码。
我正在定义一个类,该类将事件作为指针存储在成员std::vector<cl::Event*> m_lastaccesses
中。在类实例operator=
和A
之间调用B
时,将enqueueWriteBuffer
设置为blockingWrite
和CL_FALSE
的情况下调用A.m_lastaccesses[0]
它的返回事件。在退出operator=
之前,此事件已复制到*B.m_lastaccesses[1]=*A.m_lastaccesses[0]
,并且退出了operator=
。
如果我将CL_FALSE
更改为CL_TRUE
,或者在退出A.m_lastaccesses[0]->wait()
之前打电话给operator=
,则主机会有效地等待数据传输,并且一切正常。如果我转而离开CL_FALSE
并在退出A.m_lastaccesses[0]->wait()
后紧随其后打电话给operator=
,即使我确认A.m_lastaccesses[0]
指向主机,主机也不会等待与以前相同的内存地址。
我的推测是某些引用计数出乎意料,并且cl::Event
被OpenCL的C ++包装器释放或修改了
答案 0 :(得分:0)
所以...您有一个由指针组成的向量:
std::vector<cl::Event*> m_lastaccesses
...,您正在复制指针内容:
*B.m_lastaccesses[1]=*A.m_lastaccesses[0]
...您怎么知道B.m_lastaccesses[1]
是有效的指针?如果它是有效的指针,那么当该行代码覆盖该实例时,存储在该实例上的实例将如何处理?这是实际的代码吗,因为我很惊讶它完全可以工作...
我的推测是某些引用计数出乎意料地
也许。我的推测是,您正在弄乱指针和指针内容,并且在某个地方爆炸。而且我真的没有看到在这里使用指针的充分理由。我只是直接存储cl :: Event对象。 cl2.hpp中的类通常仅存储指向基础CL对象的单个指针,对其进行复制/删除很便宜(仅导致clRetain / clRelease),并且甚至可以避免带有move-assignments的clRetain / clRelease调用。在某种程度上,cl :: Event充当“智能”指针。
哦,您可以随时查看cl2.hpp的源代码。没那么复杂。