Memory OpenCL中的流媒体

Memory OpenCL中的流媒体,memory,stream,opencl,Memory,Stream,Opencl,我将编写一个OpenCL程序,在任务级别处理大量数据(不可能进一步并行,但数据量足够高) 数据本身从一个文件中读取,结果应该写入另一个文件。 现在我认为最好(最快)让一个线程读取文件并将数据推送到内核,而另一个线程获取完成的数据并将其写入文件。 所以我实际上需要像ReadData->CopyToDevice->ExecuteKernel->CopyToHost->WriteData这样的东西 有没有什么例子,如何做到最好?我从一个类似10的数组开始(队列、InputMemory、OutputMe

我将编写一个OpenCL程序,在任务级别处理大量数据(不可能进一步并行,但数据量足够高) 数据本身从一个文件中读取,结果应该写入另一个文件。 现在我认为最好(最快)让一个线程读取文件并将数据推送到内核,而另一个线程获取完成的数据并将其写入文件。 所以我实际上需要像ReadData->CopyToDevice->ExecuteKernel->CopyToHost->WriteData这样的东西

有没有什么例子,如何做到最好?我从一个类似10的数组开始(队列、InputMemory、OutputMemory、事件)。 第一个线程:读取数据,等待下一个事件条目为空,填写此数组,下一个
第二条线索:事件=null->waitforevent,写入数据,将事件设置为null 或者使用10信号量,而不是检查空值

我正在做一些图像处理的事情,但在考虑做任何事情之前,你应该先分析一下瓶颈在哪里。我不知道您的内核计算密集度有多高,但您不应该低估I/O

首先:是的,总共使用三个线程可能是隐藏I/O延迟的好主意。但是十个命令队列太多了,每个GPU一个就足够了。此外,如果您只有一个GPU,那么为它提供十个不同的缓冲区是毫无意义的,如果它只能处理一个缓冲区。因此,您最好使用双缓冲区策略并阻止读写操作。

我正在做一些图像处理的工作,但在考虑做任何事情之前,您应该实际分析一下瓶颈所在。我不知道您的内核计算密集度有多高,但您不应该低估I/O


首先:是的,总共使用三个线程可能是隐藏I/O延迟的好主意。但是十个命令队列太多了,每个GPU一个就足够了。此外,如果您只有一个GPU,那么为它提供十个不同的缓冲区是毫无意义的,如果它只能处理一个缓冲区。因此,您最好使用双缓冲区策略并阻止读写操作。

此外,使用单独的OpenCL命令队列进行上传、处理和下载,并使用巧妙的方法在它们之间创建依赖关系。当GPU支持时,这将允许硬件重叠这些操作。另外,使用单独的OpenCL命令队列进行上传、处理和下载,并使用clEvents在它们之间创建依赖关系。这将允许硬件在GPU支持时重叠这些操作

内核本身处理固定大小和可变大小输出的数据。一个CPU每秒可以处理大约10k的数据集(每个约150B),因此我考虑将大约10k的数据集分为每个组31个工作项(31个工作项是由于本地内存需求)和几个组。所以我想在将数据传输到内核时,我可以在内核中对以前的数据集进行计算,并从磁盘读取下一个数据集的数据。因此,它就像一个有4个阶段的管道:从磁盘读取、写入设备、处理数据/从设备读取、写入磁盘。例如,在一个队列中进行计算,而另一个队列正在传输数据,而不是相反。因此,同一内核被实例化2次,并在2个队列上调用。如果有足够的CU,内核甚至可以同时运行,不是吗?除了顺序之外,无法保证在非阻塞模式下如何安排传输和执行。因此,您可以使用相同的队列进行传输和执行。队列仅仅是发送GPU信息(内核执行或数据)的抽象。但为什么不试试呢?有序队列就像普通的FIFO队列一样。因此,如果我将传输和内核放入一个队列,它将按该顺序执行。因此,内核执行在传输数据之后开始。对于单个内核调用来说已经足够好了。但如果我再次将相同的文件排队,那么第二次传输将在第一个内核完成后开始。如果我将它放入另一个队列,那么传输可能会在第一个内核完成之前开始,这给了我隐藏复制延迟的优势。还是我错过了什么?啊,现在我明白你的意思了。您是对的,您可以使用两个独立的队列来传输和提交内核执行。当然,然后您需要将读/写事件传递给正在进行/后续的内核执行。内核本身处理固定大小和可变大小输出的数据。一个CPU每秒可以处理大约10k的数据集(每个约150B),因此我考虑将大约10k的数据集分为每个组31个工作项(31个工作项是由于本地内存需求)和几个组。所以我想在将数据传输到内核时,我可以在内核中对以前的数据集进行计算,并从磁盘读取下一个数据集的数据。因此,它就像一个有4个阶段的管道:从磁盘读取、写入设备、处理数据/从设备读取、写入磁盘。例如,在一个队列中进行计算,而另一个队列正在传输数据,而不是相反。因此,同一内核被实例化2次,并在2个队列上调用。如果有足够的CU,内核甚至可以同时运行,不是吗?除了顺序之外,无法保证在非阻塞模式下如何安排传输和执行。因此,您可以使用相同的队列进行传输和执行。队列仅仅是发送GPU信息(内核执行或数据)的抽象。但为什么不试试呢?有序队列就像普通的FIFO队列一样。因此,如果我将传输和内核放入一个队列,它将按该顺序执行。因此,内核执行在传输数据之后开始。对于单个内核调用来说已经足够好了。但如果我再次将相同的文件排队,那么第二次传输将在第一个内核完成后开始。如果我将它放入另一个队列,那么传输可能会在第一个内核完成whi之前开始