CUDA:为什么每个块有超过8个线程有好处?

时间:2012-07-01 18:52:50

标签: cuda

我是一名使用CUDA进行数值积分的数学家。我的理解是每个Nvidia流多处理器都有8个CUDA核心。所以对我来说,每个块使用超过8个线程似乎没有任何好处。但是,当我运行我的代码时,通过每块使用32个线程而不是每个块8个线程,我获得了巨大的性能提升。

另外我注意到使用超过12个块有很大的收益(即使我的卡只有12个流多处理器)。

这有什么理由吗?

3 个答案:

答案 0 :(得分:8)

talonmies和chaohuang在评论中提供了很好的信息,你应该调查一下(不知道为什么这些不是答案,但这是他们的电话)。无论如何,我将提供一个简短的部分答案来解释你可能不会考虑的事情。

假设您有8个控制线程和8个处理器。如果所有8个线程中的所有指令都是仅占用一个周期的片上指令,那么所有8个线程将在n个周期内完成(假设每个线程有n个总指令)。

现在假设每个控制线程由n个指令组成,其中这些指令的一小部分r是片外存储器指令,例如需要100个周期才能完成。这8个线程现在将完成[(1 - r) + 100r]n个周期。如果是r=0.1,这比前一个案例大约多11倍。

现在让我们说我们有16个线程。当第一批8个线程在慢速操作时被阻塞时,其他线程可以执行;可以执行片上指令,并且可以启动片外指令。因此,您可能只需要2[(1 - r) + 100r]n,而不需要[(1 - r) + 100r]n个周期来完成所有线程。从本质上讲,因为你有一些空间可以将等待线程与其他线程重叠,所以你可以免费添加更多线程。

这是GPU模型的强大优势:克服长延迟的大规模并行性。做一点工作需要很长时间,但没有多少时间做更多的工作。请注意,当您的算术强度(与上述公式中的r相关)较高时,与您准备隐藏延迟的工作量(线程中)相关的占用率对于峰值性能并不是那么重要。您可以使用CUDA占用计算器来查看我针对不同场景所描述的效果。

答案 1 :(得分:2)

简短的回答是延迟隐藏。

如果你只拥有与核心一样多的工作单元(线程和块)来处理它们并且执行需要数百个时钟周期才能完成的内存操作,那么GPU就没有别的办法了核心处于空闲状态,直到内存操作完成。那是在浪费计算周期。

如果您提供的工作单元数多于核心工作单元,那么当其中一个工作单元遇到长延迟内存操作时,硬件调度程序可以将其他一些工作单元交换到核心(s)这样,在长延迟内存操作完成时,内核仍然忙着进行高效工作。当混合中存在长延迟内存操作时,拥有过多的线程或块可以更好地使用所有计算周期。

答案 2 :(得分:2)

基本上有两种方法来记忆GPU中的延迟隐藏:

  1. 占用率增加,这意味着拥有比隐藏内存延迟所需的线程更多的线程。
  2. 增加每个线程的独立操作。这占用了具有所需并行性的核心。
  3. 考虑这一系列计算机指令来计算大量元素。

    a = b + c;
    d = a + c;
    

    第二条指令在等待第一条指令完成的结果时会停止。

    当您仅使用8个线程时,这些线程正在等待并且GPU核心处于空闲状态。 但是,如果您有更多线程,GPU可以安排在当前warp等待时计算其他元素的计算。这就是为什么当你增加线程数时,它的表现会更好。它更有效地利用CPU核心=)

    希望这会有所帮助〜