通过计算着色器与管道着色器实现算法


10

随着DirectX和OpenGL的计算着色器的可用性,现在可以实现许多算法而无需经过光栅化管道,而是可以在GPU上使用通用计算来解决该问题。

对于某些算法,这似乎已成为直观的规范解决方案,因为它们本质上不是基于栅格化的,而基于栅格化的着色器似乎是利用GPU功率的一种解决方法(简单的示例:创建噪声纹理。此处无需对四边形进行栅格化)。

给定一种可以双向实现的算法,与使用计算着色器相比,使用常规着色器是否有一般(潜在)的性能优势?我们是否应该注意一些缺点(例如,在运行时从计算着色器切换到计算着色器是否存在某种异常的开销)?

在两者之间进行选择时,也许还会考虑其他优点或缺点吗?


如果效果标记确实相关,那么请考虑观看Marco Fratarcangeli的Game Engine Gems“服装模拟”文章中的这段视频:youtube.com/watch ? v=anNClcux4JQ 。您可以阅读评论并发现一个尴尬的事情:基于GLSL /着色器的实现比使用CUDA或OpenCL更快(后者是由于当时驱动程序支持差,在2010年)。有一些低级的差异..有所作为。
teodron

@teodron我没有可用的GPU Gems,也找不到源代码。作者实际上是使用GLSL顶点+像素着色器还是使用GLSL计算着色器?
TravisG

是! 在CUDA之前,社区就是这样实现GPGPU功能的。以下是指向OpenCloth的链接,以了解如何使用纯GLSL或Cuda可以做到这一点:code.google.com/p/opencloth/source/browse/trunk/…–
teodron

Answers:


7

如果您要直接从compute shadrs / GPGPU方法中受益,则没有正确的答案,这在很大程度上取决于您要实现的算法类型,compute shader和CUDA / OpenCL是克服某些限制的更通用的方法旧的着色语言破解。您将获得的最重要的好处:

  • 访问空间信息。在旧的GLSL hack中(嗯,这是一个hack!),由于它使用纹理坐标,因此只提供了很少的有关邻居片段的信息。在计算着色器/ CUDA / OpenCL中,访问空间信息要灵活得多,您现在可以在GPU上使用无序纹理/缓冲区访问来实现诸如直方图均衡的算法。
  • 为您提供线程同步和原子
  • 计算空间:旧的GLSL hack会将顶点/片段计算空间硬连接到着色器。片段着色器将以片段数运行,顶点着色器将以顶点数运行。在计算着色器中,您定义自己的空间。
  • 可扩展性:与应在同一SM上执行的旧GLSL着色器不同,您的计算着色器/ CUDA / OpenCL可以扩展到可用的GPU SM(流多处理器)数量。(根据Nathan Reed的评论,他说那是不对的,并且着色器应该像计算着色器一样好地扩展。我仍然不确定是否需要检查文档)。
  • 上下文切换:应该进行一些上下文切换,但是我会说这取决于应用程序,因此最好的选择是对应用程序进行概要分析。

好吧,我认为,即使您想走计算着色器路线,即使某些算法可能更适合,但仍需要考虑某些注意事项:

  1. 硬件和向后兼容性。计算着色器仅在更新的硬件中可用,并且如果您要购买商业产品(例如游戏),则需要期望很多用户可能无法运行您的产品。
  2. 您通常需要在GPU / CPU架构,并行编程和多线程(例如,内存共享,内存一致性,线程同步,原子及其对性能的影响)方面的额外知识,而这些知识通常不需要使用普通着色器。
  3. 学习资源,根据经验,与通常的着色器路由相比,用于计算shadrs,OpenCL和CUDA(还提供OpenGL互操作性)的学习资源要少得多。
  4. 调试工具由于缺乏适当的调试,因此与大多数着色器相比,工具的开发会变得更加困难,至少可以在视觉上调试着色器。
  5. 我希望计算着色器比其他着色器中的相同算法具有更好的性能。如果正确地考虑了第2点的内容,则可以避免图形渲染的额外步骤。但是我没有任何具体证据支持我的主张。
  6. 如果您要沿着那条路线,也应该考虑将CUUDA / OpenCL用于GPGPU。

即便如此,我仍然确信这对未来非常重要,并且将是一次很棒的学习经历。祝好运!


我认为OP可能会问这个问题:为什么要使用纯GLSL着色器而不是在CUDA中对其进行编码来解决问题?有一篇有关布料模拟的游戏编程宝石文章,作者正是这样做的。GLSL hacky旧方法在性能方面优于CUDA方法。您可能应该指出为什么,如果您知道为什么。
teodron

2
我认为您的可扩展性点不正确-顶点和片段着色器与计算着色器一样能够在整个GPU上扩展。实际上,计算线程着色器可能更难扩展,因为线程组大小和共享内存使用情况可能会对一次可以运行多少个着色器线程施加更多限制。
内森·里德

2
另外,如果要填充纹理(例如,生成噪声或执行其他一些程序算法),以我的经验,如果仅在每个像素处评估公式,则片段着色器将比计算着色器快。我的猜测是,因为片段顺序与内部平铺/扭曲像素顺序匹配,因此与不知道该顺序的计算着色器相比,内存局部性更好。仅当您可以使用计算着色器的特殊功能(例如共享内存)来加快片段着色器的速度时,它才会更快。
内森·里德

2
好,最后一条评论。:)我认为当前大多数GPU在从图形到计算以及从图形到计算时都具有某种上下文切换或模式切换。因此,如果您运行一些图形着色器,然后分派计算着色器,然后运行更多的图形着色器等,则在来回切换时会导致性能下降。这是您必须分析的内容,但这可能是在特定情况下坚持使用图形着色器的另一个原因。
内森·里德

@NathanReed感谢您的评论,我将更新我的答案。
concept3d
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.