我有点迷失与一些性能与OpenCL在一个AMD (夏威夷核心或Radeon R9 390)。
该行动如下:
依赖性是:
内存传输和内核执行在两个单独的命令队列中执行。命令依赖由OpenCL中定义的GPU事件完成。
现在,整个操作被循环起来,以便使用相同的输入数据进行性能分析。
正如您在时间线中所看到的,主机在GPU上等待很长时间才能完成clWaitForEvents(),而GPU大部分时间都在闲置。您还可以看到重复的操作。为了方便起见,我还提供了所有发出的OpenCL命令的列表。
我现在的问题是:
只要把所有的命令都集中在我的脑子里(当然,保持依赖性,第一绿色必须在第一蓝色之后开始),我就可以提高三倍的性能。我不知道为什么GPU这么慢。有人有洞察力吗?
某数运算
由于内核#1比内存传输#2更快,内核#2比内存传输#3更快,所以总的时间应该是:
但clWaitForEvents是
是的,有一些损失,我很好,大约10% (60 %),但300%是太多。
发布于 2017-07-13 08:18:10
正如@DarkZeros所说,您需要通过使用多个命令队列在时间行中重叠来隐藏内核队列开销。
为什么GPU会空转这么久?
因为您使用的是两个命令队列,而且它们(可能)是连续运行的(可能),而这些事件会使它们等待时间更长。
如果所有内容都是串行的,则应该使用单个队列。如果可以添加双缓冲或类似技术来推进计算,则应该允许两个队列重叠操作。
为什么内核执行得这么晚?
宽漏洞由主机端延迟(如排队命令、设备刷新命令、主机端算法和设备端事件控制逻辑)组成。也许事件可以小到20-30微秒,但主机设备之间的交互作用更大。
如果您摆脱了事件并使用了单个队列,驱动程序甚至可以添加早期计算技术来填补这些空白,甚至在您对这些命令进行排队之前(可能),就像CPU进行早期分支(预测)一样。
为什么内存传输和内核不并行执行?
没有强制执行,但是驱动程序也可以检查内核和副本之间的依赖关系,为了保持数据的完整性,他们可以停止一些操作,直到其他一些操作完成(可能)。
您确定内核和缓冲区副本完全独立吗?
另一个原因可能是两个队列没有太多可选择的重叠。如果两个队列都有两种类型的操作,那么它们将有更多的选项可以重叠,比如内核+内核,复制+复制,而不仅仅是kernel+copy。
如果程序有太多的小内核,您可以尝试OpenCL 2.0动态并行,这使得设备调用内核本身比主机端队列更快。
也许您可以添加一个更高级别的并行性,例如图像级并行(如果它的图像处理是这样的话),以保持gpu的忙碌。同时处理5-10个映像,这应该确保独立的内核/缓冲区执行,除非所有映像都在同一个缓冲区中。如果这不起作用,那么您可以启动相同程序的5-10个进程(进程级并行)。但是,太多的上下文可能会限制驱动程序,所以图像级的并行性必须更好。
R9 390必须能够使用8-16命令队列进行处理。
1758 s
有时,即使是空的内核也会让它等待500到100秒。最可能的情况是,您应该排队1000个周期,在结束时等待一次。如果每个周期在用户单击按钮后都能工作,那么用户就不会注意到1.7ms的延迟。
https://stackoverflow.com/questions/45078951
复制