Better Performance at Lower Occupancy(二)使用更少线程隐藏内存访问延迟

来源:互联网 发布:linux线程相关系统调用 编辑:程序博客网 时间:2024/05/29 18:45

隐藏内存访问延迟,使用相同的说明方式,但针对内存操作。

  所需并行度 = 延迟 * 吞吐量

  

  所以隐藏内存延迟意味着保持100KB的数据读取速率,当然如果kernel是计算限制(compute bound)的,则这个数值可以变小。

  那么,多少线程可以达到100KB呢,有多种方法:

  1. 使用更多的线程

  2. 使用指令级并行(每个线程进行更多次存储访问)

  3. 使用位级(bit-level)并行(使用64/128位方式存储访问)

  每个线程做更多的工作,则线程数量可以更少:每个线程取回(fetch)4 Byte,需要25000个线程,取回100B,仅需要1000个线程。


  经验验证

  每个线程拷贝一个浮点数:

  

  运行多个线程块,通过动态分配共享内存来控制SM占用率。

  每个线程拷贝单个浮点数(GTX480)

  

  只能通过最大化占用率来隐藏延迟吗?不,也可以每个线程做更多的并行工作。

  

  注意,线程并不会被存储访问阻塞,它只会因为数据依赖性而阻塞。

  每个线程拷贝2个浮点数

  

  虚线部分为原曲线,所以我们可以减少占用率了。

  

  注意,本地数组会尽量分配在寄存器中,以下是每个线程拷贝4个浮点数

  


  可以看到,仅仅25%的占用率就足够了,那么我们究竟能做到什么程度?

  以下是拷贝8个浮点数:

  

  每个线程拷贝8个float2型数据

  

  每个线程拷贝8个float4型数据

  

  只通8%的占用率就达到了87%的pin带宽!

  每个线程拷贝14个float4型数据

  

  只通过4%的占用率就达到了峰值的84%。

  有两种方法来隐藏内存访问开销

  

  谬误:“低占用率常常会影响GPU隐藏内存延迟的能力,从而导致性能下降。”(CUDA Best Practices Guide)。我们刚才看到,仅仅4%的占用率就可以达到峰值的84%,注意这已经超过了cudaMemcpy所能达到的最好性能(71%)。

  谬误:“一般来说,需要更多的warps,如果对片下内存的访问指令比例。。。”(CUDA Programming Guide)错,我们刚才看到了,在一个内存访问密集型的kernel中,每个SM仅仅只有4个warps就可以达到87%的内存性能峰值。

0 0