在boost :: compute

时间:2017-06-14 14:02:16

标签: c++ memory-management boost-compute

在尝试使用boost :: compute时,我遇到了一个确定我可以在设备上分配的最大向量的问题(我对boost :: compute还是比较新的)。以下代码片段

std::vector<cl_double> host_tmp;
std::cout << "CL_DEVICE_GLOBAL_MEM_SIZE / sizeof(cl_double) = " << device.get_info<cl_ulong>(CL_DEVICE_GLOBAL_MEM_SIZE) / sizeof(cl_double) << "\n";
std::cout << "CL_DEVICE_MAX_MEM_ALLOC_SIZE / sizeof(cl_double) = " << device.get_info<cl_ulong>(CL_DEVICE_MAX_MEM_ALLOC_SIZE) / sizeof(cl_double) << "\n";
size_t num_elements = device.get_info<cl_ulong>(CL_DEVICE_MAX_MEM_ALLOC_SIZE) / sizeof(cl_double);
compute::vector<cl_double> dev_tmp(context);
std::cout << "Maximum size of vector reported by .max_size() = " << dev_tmp.max_size() << "\n";
for (auto i = 0; i < 64; ++i) {
    std::cout << "Resizing device vector to " << num_elements << "...";
    dev_tmp.resize(num_elements, queue);
    std::cout << " done.";
    std::cout << " Assigning host data...";
    host_tmp.resize(num_elements);
    std::iota(host_tmp.begin(), host_tmp.end(), 0);
    std::cout << " done.";
    std::cout << " Copying data from host to device...";
    compute::copy(host_tmp.begin(), host_tmp.end(), dev_tmp.begin(), queue);
    std::cout << " done.\n";
    num_elements += 1024 * 1024;
}

给出

CL_DEVICE_GLOBAL_MEM_SIZE / sizeof(cl_double) = 268435456
CL_DEVICE_MAX_MEM_ALLOC_SIZE / sizeof(cl_double) = 67108864
Maximum size of vector reported by .max_size() = 67108864
Resizing device vector to 67108864... done. Assigning host data... done. Copying data from host to device... done.
Resizing device vector to 68157440... done. Assigning host data... done. Copying data from host to device... done.
...
Resizing device vector to 101711872...Memory Object Allocation Failure

很明显,报告的max_size()既不是硬限制也不是强制执行。 我认为为了安全起见我应该坚持报告的max_size(),但是,如果我在大小为max_size()的设备上分配多个向量,那么我也会收到Memory Object Allocation Failure消息。

  1. 使用boost :: compute时,处理(并避免)内存分配失败的正确/通常方法是什么?
  2. 如何确定我可以在任何给定时刻分配的矢量的最大大小(即设备可能已经包含已分配的数据)?
  3. 如果我有太多的数据,我可以让boost :: compute自动处理它或者我是否必须自己分解它?
  4. 完成设备后,如何释放设备上的内存?

1 个答案:

答案 0 :(得分:1)

  
      
  1. 使用boost :: compute时,处理(并避免)内存分配失败的正确/通常方法是什么?
  2.   

您只需遵循与OpenCL相同的规则即可。 Boost.Compute不会添加任何新限制。您必须记住,在许多OpenCL平台上,缓冲区的分配内存是以惰性方式完成的,因此即使创建大小大于CL_DEVICE_MAX_MEM_ALLOC_SIZE的缓冲区成功,它也会在以后失败(实现定义的行为)。

  
      
  1. 如何确定我可以在任何给定时刻分配的矢量的最大大小(即设备可能已经包含已分配的数据)?
  2.   

我认为不可能。您始终可以创建分配器类(并将其与boost::compute::vector一起使用),这将全局跟踪每个设备(使用CL_DEVICE_GLOBAL_MEM_SIZE)并执行您希望它做的任何事情,如果还不够记忆。但是,您必须记住OpenCL内存绑定到上下文而不是设备。

  
      
  1. 如果我有太多的数据,我可以让boost :: compute自动处理它们,还是我必须自己分解?
  2.   

不,你必须实施一些能够解决这个问题的事情。它可以通过多种方式完成,具体取决于您的OpenCL平台和支持的OpenCL版本。

  
      
  1. 完成设备后,如何释放设备上的内存?
  2.   

boost::compute::vector析构函数释放设备内存。每个OpenCL内存对象(如缓冲区)都有其引用计数器,可通过Boost.Compute的类正确增加和减少。注意:迭代器不拥有缓冲区,因此在释放底层缓冲区后(例如,在分配了该缓冲区的boost::compute::vector之后),迭代器停止工作。