Performance 处理离散图像时优化GPU利用率的技术

Performance 处理离散图像时优化GPU利用率的技术,performance,opengl,image-processing,gpu,hpc,Performance,Opengl,Image Processing,Gpu,Hpc,我有一个服务器,它将过滤器(实现为OpenGL着色器)应用于图像。它们大多是直接的颜色映射,但偶尔也会出现模糊和其他卷积 源图像是PNG和JPG,大小从100x100像素到16384x16384(我的GPU的纹理大小)不等 管道是: Decode image to RGBA (CPU) | V Load texture to GPU | V Apply shader (GPU) | V Unlo

我有一个服务器,它将过滤器(实现为OpenGL着色器)应用于图像。它们大多是直接的颜色映射,但偶尔也会出现模糊和其他卷积

源图像是PNG和JPG,大小从100x100像素到16384x16384(我的GPU的纹理大小)不等

管道是:

Decode image to RGBA (CPU)
        |
        V
Load texture to GPU
        |
        V
   Apply shader (GPU)
        |
        V
Unload to CPU memory
        |
        V
  Encode to PNG (CPU)
GPU的平均加载时间约为0.75ms,卸载时间约为1.5ms,处理纹理时间约为1.5ms

我有多个CPU线程解码PNG和JPG,为GPU提供连续的工作流

挑战在于
watch-n 0.1 nvidia smi
报告GPU的使用率大致在0%-1%之间,周期性地达到18%

我真的很想从GPU中获得更多的价值,也就是说我希望它的负载至少在50%左右。我的问题是:

  • nvidia smi
    是否合理地表示了GPU的繁忙程度?例如,它是否包括加载和卸载纹理的时间?如果没有,我是否可以使用更好的指标

  • 假设是这样,而GPU什么也不做,那么有没有什么众所周知的架构可以提高吞吐量?我曾考虑过将多个图像平铺到一个大纹理中,但这会让CPU使用率而不是GPU使用率大打折扣

  • 在GPU处理前一幅图像时,是否有办法将下一幅图像加载到GPU纹理内存


采样
nvidia smi
是一种非常糟糕的计算利用率的方法。使用(我发现这是最容易处理的)或了解您的性能和瓶颈的真实情况

如果不查看代码,不更好地理解瓶颈是什么,就很难说如何提高性能

  • 你说你有多个CPU线程在运行,但是你有多个CPU线程来隐藏数据传输的延迟吗?这允许您在GPU处理时将数据加载到GPU中
  • 你确定你有线程而没有进程吗?线程可能会减少开销
  • 在GPU上应用单个着色器几乎不需要时间,因此您的管道最终可能会受到硬盘速度或总线速度的限制。您是否查阅了此规格,测量了图像的大小,并找到了最大处理能力的理论值?你的GPU很可能会花很多时间闲置,除非你在上面做很多复杂的数学运算

对于直接颜色映射,不应使用GPU。在CPU里做肯定更快。我可能在简化的时候误导了你。(大多数)着色器正在动态计算颜色映射,但计算非常简单,即亮度增强,不需要卷积或内核。@DaveDurbin:“在GPU处理前一幅图像时,有没有办法将下一幅图像加载到GPU纹理内存?”你怎么还没有这样做?您是否正在尝试上载到当前正在使用的图像?我的意思是,这似乎是一个非常简单的三重缓冲的例子。感谢指向CUDA streams和NVIDIA Nsight的指针,我正在寻找可以与AWS Cloudwatch集成的基于CLI的工具。数据传输的许多复杂性隐藏在OpenGL调用后面。我曾考虑过使用CUDA而不是OpenGL,因为单个着色器非常简单,而且处理过程中的重叠数据传输似乎可以提高吞吐量,但我不确定这是否可行。我来看看。@DaveDurbin:visualprofiler和Nsight可以用来控制无头机器上的远程进程。CLI工具
nvprof
也可用于生成输出,稍后可在NVVP中进行分析。