Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.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
OpenCL使用大量主机内存将内核排队_Opencl - Fatal编程技术网

OpenCL使用大量主机内存将内核排队

OpenCL使用大量主机内存将内核排队,opencl,Opencl,我正在使用OpenCL内核对系统的大量副本执行蒙特卡罗扫描。在初始调试阶段之后,我将一些参数增加到更实际的值,并注意到程序突然占用了大量主机内存。我在大约4000个副本上执行1000次扫描,每次扫描由2个内核调用组成。这将导致大约800万次内核调用 内存使用的来源很容易找到(参见屏幕截图) 当内核执行排队时,内存使用率会上升 内核执行时,内存使用保持不变 一旦内核用完,使用就会下降到原来的状态 我没有分配任何内存,从内存快照中可以看出 这意味着OpenCL驱动程序正在使用内存。我知道它必须

我正在使用OpenCL内核对系统的大量副本执行蒙特卡罗扫描。在初始调试阶段之后,我将一些参数增加到更实际的值,并注意到程序突然占用了大量主机内存。我在大约4000个副本上执行1000次扫描,每次扫描由2个内核调用组成。这将导致大约800万次内核调用

内存使用的来源很容易找到(参见屏幕截图)

  • 当内核执行排队时,内存使用率会上升
  • 内核执行时,内存使用保持不变
  • 一旦内核用完,使用就会下降到原来的状态
  • 我没有分配任何内存,从内存快照中可以看出

这意味着OpenCL驱动程序正在使用内存。我知道它必须保留内核调用的所有参数的副本,以及全局和本地工作组的大小,但这并不能相加

峰值内存使用率为4.5GB。在排队之前,使用了大约250MB的内核。这意味着OpenCL在800万次调用中使用了大约4.25GB,即每次调用大约半KB

因此,我的问题是:

  • 这种内存使用是正常的吗
  • 是否有好的/已知的技术来减少内存使用
  • 也许我不应该同时让这么多内核排队,但我如何做到这一点而不引起同步,例如使用
    clFinish()

需要以位控制的方式将大量内核调用排队,以便命令队列不会占用太多内存。首先,<代码> CLFLUSS可能在一定程度上有助于<代码> CWAITITFARECTS < /C> >在中间生成同步点是必要的,例如,2000个内核调用被排队,而 CWAITITFARECTS < /代码>等待第一千个内核调用。设备不会暂停,因为我们已经预批处理了另外1000次工作调用。然后类似的事情需要一次又一次地重复。这可以这样说明:

enqueue 999 kernel commands
while(invocations < 8000000)
{
    enqueue 1 kernel command with an event
    enqueue 999 kernel commands
    wait for the event
}
999内核命令排队
而(调用次数<8000000次)
{
使用事件将1内核命令排队
将999内核命令排队
等待事件
}

我们应该等待的最佳内核调用次数可能与此处给出的不同,因此需要针对给定的场景进行计算。

尝试
clFlush
每100或1000次内核调用一次,或者如果您观察到它会影响性能,则更少尝试。这是一个非阻塞命令,它将向设备发出所有以前排队的命令。感谢您的提示!在每1000次内核调用之后,我就添加了一个
clFlush
,这已经稍微改进了一点。峰值内存使用下降到3.5GB,峰值更短,即下降斜率开始得更早,但没有那么陡峭。对性能的影响很小或不存在,我看不到任何影响。好的,请尝试
clWaitForEvents
。将1000个内核放入队列,在最后一个内核上添加一个事件,然后将另外999个内核放入队列,并调用
clWaitForEvents
。这将使它等待第1000个内核完成,同时队列中还有另外999个内核。然后同样地重复整个过程。很好,这使它下降到750MB。
clWaitForEvents
之前的
clFlush
有意义吗?我没有注意到任何区别。
clFlush
就在
clWaitForEvents
之前,而不是因为我认为它是由
clWaitForEvents
完成的。如果你想把内存减少到750MB以上,我会尽量减少等待内核完成的时间,例如,减少到500。这个数字需要计算出来,这样才能最适合您的场景。我将把我们在这里所做的作为一个答案,如果你高兴的话,接受它。