【问题标题】:OpenCL's enqueueWriteBuffer causes __memcpy_sse2_unaligned segmentation faultOpenCL 的 enqueueWriteBuffer 导致 __memcpy_sse2_unaligned 分段错误
【发布时间】:2018-03-18 19:54:47
【问题描述】:

我有以下 OpenCL 代码,使用 C++ Wrapper 和英特尔的 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]);

当它使用 -O3、march=native 和 mtune=native 标志编译时,它会导致来自 TBB 代码的以下分段错误:

__memcpy_sse2_unaligned() 在 memcpy-sse2-unaligned.S:116 0x7ffff6e64ba4

没有任何优化,程序运行良好。

我将问题追溯到 queue.enqueueWriteBuffer 调用,没有它我没有任何问题。

我试图注释掉修改变量“数据”的部分代码,以防我访问无效的内存位置,但问题仍然存在。

如果我从 std::vector 中删除对齐分配器,没有优化的构建也会开始中断。

我总共有 70MB 试图存储在这个缓冲区中,远小于 CL_DEVICE_MAX_MEM_ALLOC_SIZE 报告的 3.8GB。但是如果我减小数组的大小,问题就会停止。我在后一种情况下尝试的尺寸是 5。

我还决定打印向量分配的地址,它是 0x7f21b797f010,所以它至少对齐到 16 个字节。

编辑:关于多线程,数组的创建以及 OpenCL 操作发生在同一方法中,并且在主线程中。命令队列不是用异步标志创建的,缓冲区写入后有一个flush()操作。

可能是什么问题?

谢谢

【问题讨论】:

  • 投反对票的人可以澄清原因,以及关闭主题的关闭请求吗?
  • 当您使用异步写入时,您是否确保在保证完成enqueueWriteBuffer 操作之前不会破坏/调整 SampleArray 的大小?
  • @pmdj 数组的创建以及 OpenCL 操作发生在同一方法和主线程中。我已经用更多信息编辑了这个问题。
  • clFlush 不保证复制操作会完成,只是会开始。您需要等待事件触发,或者将 true 作为“阻塞”参数传递。当向量超出范围时,OpenCL 可能仍在忙于复制您的数据。
  • 确实,添加 clFinish 解决了这个问题。请正式将其转换为答案,以便我标记它。

标签: c++ segmentation-fault opencl memory-alignment


【解决方案1】:

正如在 cmets 中的对话中所证实的,这里的问题是 enqueueWriteBuffer() 操作是非阻塞的(CL_FALSE 作为 blocking 参数传递)并且源缓冲区(@987654323 @vector) 在保证底层复制操作完成之前超出范围。

至少有 4 种可能的解决方案:

  1. 使用enqueueWriteBuffer() 的阻止形式。如文档所示,在这种情况下,一旦函数返回,源缓冲区将不会被访问。
  2. 捕获返回的事件并在SampleArray() 超出范围之前调用clWaitForEvents() 或调用clFinish()。仅当您的程序在此期间执行任何实质性操作时,这才比阻塞变体更可取。
  3. 将源数据保留足够长的时间。
  4. 不要使用enqueueWriteBuffer() 的复制形式:使用NULL 源创建缓冲区,将其映射到应用程序的内存空间,将数据写入其中,然后取消映射。这可能会完全避免复制,至少在集成 GPU/APU 上是这样)

这些大致按并行度/效率递增的顺序排列。

【讨论】:

    猜你喜欢
    • 2011-04-13
    • 2017-11-02
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2020-12-31
    • 2019-07-21
    相关资源
    最近更新 更多