0%

【文献阅读08】SLI Best Practices

说点什么

最近比较忙,所以最近就没看GAMES101的系列课程了,应科研需要,近期读了一下SLI的技术文档,想将一些有用的内容进行分享一下

原文链接

SLI Best Practices

SLI技术总结

SLI技术是什么:Scalable Link Interface,是一种通过多个NVIDIA的GPU划分负载,以提高渲染性能的多GPU配置。

SLI提供的五种多GPU渲染的模式:

  1. Alternate Frame Rendering(AFR):多个GPU交替渲染帧,比如在两个GPU的场景下,GPU1渲染帧1,GPU2渲染帧2,然后GPU1再渲染帧3,以此类推。该方式只需要很少的GPU间通信,但由于GPU间性能差距、以及无法减少帧延迟(操作到显示的时间)、CPU的性能上限,因此该模式不容易进行扩展。此外,还有两种可解决的影响AFR扩展的问题:CPU-GPU间同步和帧间依赖产生的GPU同步。
  2. Split Frame Rendering(SFR):将一帧的画面划分为多个区域,每一个GPU负责一个区域,划分的区域会因为负载进行动态改变以保证负载均衡。该模式可能会产生重复的计算和GPU间的通信开销。
  3. AFR of SFR:该模式将GPU分组,组内的GPU采用SFR的模式,组与组之间采用AFR的模式,比如4个GPU,分成两个AFR组,每个组内的两个GPU以SFR的模式运行。
  4. Boost Performance Hybrid SLI Rendering:该模式类似于AFR模式,然而该模式是针对性能差距较大的GPU的场景的,比如两个GPU的场景下,GPU1的性能时GPU2的两倍,则GPU1渲染帧1和帧2,GPU2渲染帧3,然后GPU1渲染帧4和帧5,以此类推。
  5. SLIAA:该模式在保证原有的帧率的情况下,通过多个GPU在不同的位置进行采样,并最终进行合并,以提升抗锯齿的性能。

关于SLI的GPU内存的说明

CPU中任何数据的更新都会被广播到所有GPU,每一个GPU都存放了一份数据的备份。(个人见解:存储的数据存在大量的冗余,不能充分利用每个GPU的显存)

AFR的帧间依赖

渲染到纹理

对于SwapChain而言,可以通过设置discard flag(不同DX版本的flag不同),告诉驱动back buffer中的数据不必保留(不必传输到其他的AFR组或GPU中)

对于Render Target而言,没有这个flag,这是由于不知道应用在未来的帧中是否需要被写入Render Target的数据,因此,需要将该数据同步至所有的AFR组或GPU中。这导致GPU间大量的数据在传输,以及同步开销。比如:GPU2将暂停等待GPU1更新共享的Render Target。(该问题可以通过修改SLI的配置文件以阻止帧间的render target传输,或者通过在每一帧开会前调用Clear()函数清除Render Target使得驱动认为改数据不必保留并放弃该Render target的拷贝以解决)

D3D10及以后的Stream Out buffer

和Render target类似,buffer也有类似的问题,但由于没有API机制以清除Buffer,因此只能通过将SLI配置文件添加到驱动程序中。

D3D11中的Unordered Access Views

D3D11中引入的Unordered Access Views概念,可以将其绑定到管线进行随机读写访问。由于任何可能的修改都有可能导致帧间的依赖,因此在缺少配置文件的情况下,应用程序会通过引入适当的帧间同步操作来处理。ID3D11DeviceContext::ClearUnorderedAccessViewUint和ID3D11DeviceContext::ClearUnorderedAccessViewFloat这两个调用可以在每一帧前清除UAV buffer,因此可以去除这种帧间依赖以避免AFR组间的同步开销