我有一个奇怪的问题,一个运行良好的应用程序,但有一些无理的性能丢失。应用程序和代码是私有的,但我可以在这里给它一些详细的工作模式(简化了很多)。
我的应用使用4个内核:
1. Preprocesses
Reads "I" buffer; Writes to "T" buffer
2. Process
Reads + Writes "T" buffer
3. Parse & Preprocess
Reads + Writes "T" buffer, & writes "O" buffer
4. Check
Reads "O" buffer; Writes to "C" buffer (result of Check)
所有缓冲区都保存在设备中。 “I”和“O”缓冲区各为200kB缓冲区。 “T”缓冲区大约为20MB,从不在GPU外部使用。 “C”缓冲区只是一个4字节的int给出了结果。
系统以3种不同的形式运行:
- Pure iterative: Write,1,2,3,2,3,2,3,.....,2,3,Read
- Iterative + Reading intermediate: Write,1,2,3,Read,2,3,Read,2,3,.....,2,3,Read
- Iterative + Check: Write,1,2,3,4,Read(C),2,3,4,Read(C),2,3,.....,2,3,Read
在第一种模式下,所有内核都会立即排队,我对该模式没有任何问题,只需运行最大GPU利用率(和CPU)。 其他2种模式使用内核的渐进式排队,如果读取值不正确,则会对一组新内核进行排队。
然而,在第二和第三模式中,在每次从设备读取之后,设备保持空闲一段时间。我对该程序进行了描述,每次读取后都有一小部分(100us)没有GPU使用时间。写入部分后不会发生这种情况。 我为I / O和执行创建了2个独立的队列,以实现并行化,没有运气。
差距是这样的(明天我可以发布一个Visual Profiler的屏幕):
- 写入,1,2,3-,读取,2, GAP 下,如图3所示,读取,2, GAP 下,3,...,2,3 ,读取
就我测试的HD5770,HD5570,GTX570,C2050,C2070而言,此问题出现了。而在Windows和Linux中。 但在Quadro 2000M中运行完全正常,甚至可以执行并行内核执行和I / O !!
有什么我想念的吗?固定内存比手动clCreate + clWrite / Read更快吗?它可以解决这个问题吗? 我意识到我可以在那个间隙中运行内核2多次,但不可能运行内核3,内存“O”是否以某种方式受到保护并阻止内核3运行?
PD:我在有间隙的模式下有一些clWaitForEvents。我测试了删除它们,差距减少了约50%,但CPU使用率从20%增加到100%。这可能与CPU或调度程序/驱动程序有关吗?