CUDA如何阻止/扭曲/线程映射到CUDA核心?

Dae*_*lus 133 cuda gpgpu nvidia warp-scheduler

我已经使用CUDA几周了,但我对块/ warps/thread的分配有些怀疑. 我从教学的角度(大学项目)研究建筑,所以达到最佳表现并不是我关注的问题.

首先,我想了解我是否直截了当地得到了这些事实:

  1. 程序员编写内核,并在线程块网格中组织其执行.

  2. 每个块都分配给一个流式多处理器(SM).一旦分配,它就无法迁移到另一个SM.

  3. 每个SM将其自己的块拆分为Warps(当前最大大小为32个线程).warp中的所有线程在SM的资源上并发执行.

  4. 线程的实际执行由SM中包含的CUDA核执行.线程和核心之间没有特定的映射.

  5. 如果warp包含20个线程,但目前只有16个可用核心,则warp将不会运行.

  6. 另一方面,如果一个块包含48个线程,它将被分成2个warp并且它们将并行执行,前提是有足够的内存可用.

  7. 如果线程在核心上启动,则它会因内存访问或长时间浮点操作而停止,其执行可以在不同的核心上恢复.

他们是对的吗?

现在,我有一个GeForce 560 Ti,因此根据规格,它配备了8个SM,每个包含48个CUDA核心(总共384个核心).

我的目标是确保架构的每个核心都执行相同的SAME指令.假设我的代码不需要比每个SM中可用的代码更多的寄存器,我想象了不同的方法:

  1. 我创建了8个块,每个48个线程,因此每个SM有1个块来执行.在这种情况下,48个线程将在SM中并行执行(利用它们可用的所有48个内核)?

  2. 如果我推出64个6个线程的块,有什么区别吗?(假设它们将在SM之间平均映射)

  3. 如果我在预定的工作中"淹没"GPU(例如,创建每个1024个线程的1024个块),可以合理地假设所有核心将在某个点使用,并且将执行相同的计算(假设线程永远不会失速)?

  4. 有没有办法使用Profiler检查这些情况?

  5. 这个东西有没有参考?我阅读了"编程大规模并行处理器"和"CUDA应用程序设计与开发"中的CUDA编程指南和专用于硬件架构的章节; 但我无法得到准确的答案.

Gre*_*ith 115

两个最好的参考是

  1. NVIDIA Fermi Compute Architecture白皮书
  2. GF104评论

我会尽力回答你的每一个问题.

程序员将工作划分为线程,将线程划分为线程块,将线程块划分为网格.计算工作分配器将线程块分配给流式多处理器(SM).一旦将线程块分配给SM,就会分配线程块的资源(warp和共享内存),并将线程划分为32个线程的组,称为warps.一旦分配了warp,它就被称为主动warp.两个warp调度程序每个周期选择两个活动warp并将warp调度到执行单元.有关执行单元和指令调度的更多详细信息,请参见 7-10页和第2节.

4'.laneid(warp中的线程索引)和核心之间存在映射.

5'.如果warp包含少于32个线程,则在大多数情况下,它将执行与具有32个线程相同的线程.由于以下几个原因,Warp可以有少于32个活动线程:每个块的线程数不能被32整除,程序执行一个发散块,因此未采用当前路径的线程被标记为非活动状态,或者warp中的线程退出.

6'.线程块将分为WarpsPerBlock =(ThreadsPerBlock + WarpSize - 1)/ WarpSize不需要warp调度程序从同一个线程块中选择两个warp.

7'.执行单元不会在内存操作上停止.如果在准备好分派指令时资源不可用,则将来当资源可用时将再次分派指令.Warp可能会在障碍,内存操作,纹理操作,数据依赖性等方面停滞不前......失败的warp不适合由warp调度程序选择.在Fermi上,每个周期至少有2个符合条件的warp非常有用,这样warp调度程序就可以发出指令.

有关GTX480和GTX560之间的差异,请参阅参考文献2.

如果你阅读参考资料(几分钟),我想你会发现你的目标没有意义.我会尽力回应你的观点.

1'.如果你启动内核<<< 8,48 >>>你将获得8个块,每个块有2个经线32和16个线程.无法保证将这8个块分配给不同的SM.如果将2个块分配给SM,则每个warp调度器可以选择warp并执行warp.您将只使用48个核心中的32个.

2'.8个48个线程的块和64个6个线程的块之间存在很大差异.假设你的内核没有分歧,每个线程执行10条指令.

  • 8个块,48个线程= 16个经线*10个指令= 160个指令
  • 具有6个线程的64个块= 64个经线*10个指令= 640个指令

为了获得最佳效率,工作分工应该是32个线程的倍数.硬件不会合并来自不同warp的线程.

3'.如果内核没有最大化寄存器或共享内存,GTX560一次可以有8个SM*8块= 64个块或8个SM*48 warp = 512个warp.在任何特定时间,部分工作将在SM上激活.每个SM都有多个执行单元(超过CUDA内核).在任何给定时间使用哪些资源取决于应用程序的warp调度程序和指令组合.如果您不进行TEX操作,那么TEX单元将处于空闲状态.如果不进行特殊的浮点运算,SUFU单元将空闲.

4'.Parallel Nsight和Visual Profiler显示

一个.执行IPC

湾 发布IPC

C.每个活动周期的活动扭曲

d.每个活动周期符合条件的扭曲(仅限Nsight)

即 经纱失速原因(仅限Nsight)

F.每条指令执行的活动线程

分析器不显示任何执行单元的利用率百分比.对于GTX560,粗略估计是IssuedIPC/MaxIPC.对于MaxIPC,假设GF100(GTX480)为2 GF10x(GTX560)为4但目标为3是更好的目标.

  • CUDA 核心是单精度 FP 单元的数量。根据 CUDA 核心来思考执行是不正确的。每个经纱有 32 个线程。这些线程将被分配给一组执行单元(例如16个cuda核心)。为了在单个时钟中向所有 48 个核心发出指令,两个 warp 调度程序之一需要选择一个满足超标量对要求的 warp,并且两条指令都必须是由 CUDA 核心执行的类型。此外,另一个 warp 调度程序必须选择一个 warp,其下一条指令将由 CUDA 核心执行。 (2认同)
  • 在您的示例中,每个调度程序都在选择warp并发出1条指令.在这种情况下,将仅使用2组执行单元.为了使用更多的执行单元,调度程序必须具有双重问题.如参考文献中所示,存在多种类型的执行单元(不仅仅是创建的cuda核心),并且存在必须满足调度器双重问题的指令配对规则(没有详细记录). (2认同)

小智 8

"E.如果warp包含20个线程,但目前只有16个核心可用,则warp将不会运行."

是不正确的.您通常意义上的核心(也用于CPU)令人困惑 - GPU中的"多处理器"数量,nVIDIA营销中的核心说话("我们的卡有数千个CUDA核心").

warp本身只能在单个核心(=多处理器)上进行调度,并且可以同时运行多达32个线程; 它不能使用多个核心.

数字"48 warps"是具有计算能力2.x的nVIDIA GPU上每个多处理器的活动warp(可选择在下一个周期中,在任何给定周期工作的warp)的最大数量; 这个数字对应1536 = 48 x 32个线程.

基于此网络研讨会的答案

  • 单核(= 多处理器)?我认为问题假设术语“单核=处理器”而不是“多处理器”。根据您的术语,您的答案是正确的。 (2认同)