OpenCL&x27;s排队写入缓冲区导致u memcpy_sse2_未对齐分段错误 我有以下OpenCL代码,使用C++包装器和英特尔OpenCL工具包: #include <Eigen/StdVector> ... typedef Sample_t float typedef std::vector<Sample_t, Eigen::aligned_allocator<Sample_t> > SampleArray; ... SampleArray data(ns * nt); ... mdata = cl::Buffer(context, CL_MEM_READ_ONLY, sizeof(Sample_t) * data.size()); queue.enqueueWriteBuffer(mdata, CL_FALSE, 0, sizeof(Sample_t) * data.size(), &data[0]); #包括 ... typedef样本浮点数 typedef std::向量采样阵列; ... 样本阵列数据(ns*nt); ... mdata=cl::Buffer(上下文,cl\u MEM\u只读,sizeof(Sample\u t)*data.size()); queue.enqueueWriteBuffer(mdata,CL_FALSE,0,sizeof(Sample_t)*data.size(),&data[0]);
当使用-O3、march=native和mtune=native标志编译时,会导致TBB代码出现以下分段错误: __memcpy_sse2_unaligned()位于memcpy-sse2-unaligned.S:116 0x7ffff6e64ba4 没有任何优化,程序运行良好 我将问题追溯到queue.enqueueWriteBuffer调用,没有它我就没有任何问题 我试图注释掉修改变量“data”的代码部分,以防访问无效的内存位置,但问题仍然存在 如果我从std::vector中删除对齐的_分配器,那么没有优化的构建也会开始中断 总的来说,我试图在这个缓冲区中存储70MB,远低于CL_DEVICE_MAX_MEM_ALLOC_SIZE报告的3.8GB。但是如果我减小数组的大小,问题就停止了。我在后面的案例中尝试的尺寸是5 我还决定打印向量分配的地址,它是0x7f21b797f010,因此它至少与16个字节对齐 编辑:关于多线程,数组的创建以及OpenCL操作都是在同一个方法和主线程中进行的。命令队列不是使用异步标志创建的,并且在缓冲区写入后有一个flush()操作 有什么问题吗OpenCL&x27;s排队写入缓冲区导致u memcpy_sse2_未对齐分段错误 我有以下OpenCL代码,使用C++包装器和英特尔OpenCL工具包: #include <Eigen/StdVector> ... typedef Sample_t float typedef std::vector<Sample_t, Eigen::aligned_allocator<Sample_t> > SampleArray; ... SampleArray data(ns * nt); ... mdata = cl::Buffer(context, CL_MEM_READ_ONLY, sizeof(Sample_t) * data.size()); queue.enqueueWriteBuffer(mdata, CL_FALSE, 0, sizeof(Sample_t) * data.size(), &data[0]); #包括 ... typedef样本浮点数 typedef std::向量采样阵列; ... 样本阵列数据(ns*nt); ... mdata=cl::Buffer(上下文,cl\u MEM\u只读,sizeof(Sample\u t)*data.size()); queue.enqueueWriteBuffer(mdata,CL_FALSE,0,sizeof(Sample_t)*data.size(),&data[0]);,c++,segmentation-fault,opencl,memory-alignment,C++,Segmentation Fault,Opencl,Memory Alignment,当使用-O3、march=native和mtune=native标志编译时,会导致TBB代码出现以下分段错误: __memcpy_sse2_unaligned()位于memcpy-sse2-unaligned.S:116 0x7ffff6e64ba4 没有任何优化,程序运行良好 我将问题追溯到queue.enqueueWriteBuffer调用,没有它我就没有任何问题 我试图注释掉修改变量“data”的代码部分,以防访问无效的内存位置,但问题仍然存在 如果我从std::vector中删除对齐的_
谢谢正如在评论中的对话中所确认的,这里的问题是
enqueueWriteBuffer()
操作是非阻塞的(CL\u FALSE
作为阻塞参数传递),并且源缓冲区(SampleArray
vector)在基础复制操作保证完成之前超出范围
至少有4种可能的解决方案:
enqueueWriteBuffer()
的阻塞形式。如文档所示,在这种情况下,一旦函数返回,就不会访问源缓冲区SampleArray()
超出范围之前调用clWaitForEvents()
或调用clFinish()
。如果您的程序在此期间正在做任何实质性的工作,那么这实际上比阻塞变体更可取enqueueWriteBuffer()
的复制形式:创建一个源为空的缓冲区,将其映射到应用程序的内存空间,将数据写入其中,然后取消映射。这可能避免完全复制,至少在集成GPU/APU上)这些基本上是按照并行性/效率的递增顺序进行的。正如在注释中的对话中确认的,这里的问题是
enqueueWriteBuffer()
操作是非阻塞的(CL\u FALSE
作为阻塞参数传递),并且源缓冲区(SampleArray
vector)在基础复制操作保证完成之前超出范围
至少有4种可能的解决方案:
enqueueWriteBuffer()
的阻塞形式。如文档所示,在这种情况下,一旦函数返回,就不会访问源缓冲区SampleArray()
超出范围之前调用clWaitForEvents()
或调用clFinish()
。如果您的程序在此期间正在做任何实质性的工作,那么这实际上比阻塞变体更可取enqueueWriteBuffer()
的复制形式:创建一个源为空的缓冲区,将其映射到应用程序的内存空间,将数据写入其中,然后取消映射。这可能避免完全复制,至少在集成GPU/APU上)这些基本上是按照并行性/效率的递增顺序排列的。请向下投票人澄清原因,以及偏离主题的结束请求?因为您使用的是异步写入,在确保
enqueueWriteBuffer
操作完成之前,您是否确保不会销毁/调整SampleArray的大小?@pmdj数组的创建以及OpenCL操作在同一方法和主线程中发生。我已编辑了包含更多信息的问题。clFlush不保证复制操作将完成,只保证复制操作将开始。您需要等待事件触发,或者将true作为“阻塞”参数传递。当向量超出范围时,OpenCL可能仍在忙于复制数据。事实上,添加clFinish解决了这个问题。请将此转换为正式答案,以便我可以标记它。downvoter可以,请,澄清原因,以及脱离主题的结束请求?因为您使用的是异步写入,在确保enqueueWriteBuffer
操作完成之前,您是否确保不会销毁/调整SampleArray的大小?@pmdj数组的创建以及OpenCL操作在同一方法和主线程中发生。我已编辑了包含更多信息的问题。clFlush不保证复制操作将完成,只保证复制操作将开始。您需要等待事件触发,或者将true作为“阻塞”参数传递。当向量超出范围时,OpenCL可能仍在忙于复制数据。事实上,添加clFinish解决了这个问题。请把这个正式地变成一个答案,这样我就可以标记它了。