我对nvidia GPU的任务调度有一些疑问.
(1)如果一个块(CTA)中的线程扭曲已经完成但是还有其他的warp运行,那么这个warp会等待其他的完成吗?换句话说,当所有线程都完成时,块中的所有线程(CTA)都会释放它们的资源,这样可以吗?我认为这一点应该是正确的,因为块中的线程共享共享内存和其他资源,这些资源在CTA大小管理器中分配.
(2)如果一个块(CTA)中的所有线程都挂起了一些长延迟,例如全局内存访问?一个新的CTA线程会占用像CPU这样的方法的资源吗?换句话说,如果一个块(CTA)已被分派到SM(流处理器),它是否会占用资源直到它完成?
如果有人向我推荐一些关于GPU架构的书或文章,我将不胜感激.谢谢!
只有当SM有足够的资源用于线程块(共享内存,warp,寄存器,屏障......)时,Compute Work Distributor才会在SM上调度线程块(CTA).分配线程块级资源,例如共享存储器.allocate为线程块中的所有线程创建了足够的warp.资源管理器将warp循环分配给SM子分区.每个SM子分区包含一个warp调度程序,寄存器文件和执行单元.一旦将warp分配给子分区,它将保留在子分区上,直到它完成或被上下文切换(Pascal体系结构)预先占用.在上下文切换恢复时,warp将恢复为相同的SM相同的warp-id.
当warp中的所有线程都已完成时,warp调度程序等待warp发出的所有未完成指令完成,然后资源管理器释放包含warp-id和register file的warp级资源.
当线程块中的所有warp完成时,块资源被释放,并且SM通知Compute Work Distributor块已完成.
一旦将warp分配给子分区并且分配了所有资源,warp就被认为是活动的,这意味着warp调度程序正在主动跟踪warp的状态.在每个循环中,warp调度程序确定哪些活动warp被停止以及哪些有资格发出指令.warp调度程序选择符合优先级的最高优先级warp并从warp发出1-2个连续指令.双重问题的规则特定于每个体系结构.如果warp发出内存加载,它可以继续执行独立的指令,直到它到达依赖指令.然后,warp将报告停滞,直到负载完成.从属数学指令也是如此.SM架构旨在通过在warp之间切换每个周期来隐藏ALU和内存延迟.
这个答案没有使用术语CUDA核心,因为这会引入一个不正确的心智模型.CUDA内核是流水线单精度浮点/整数执行单元.问题率和依赖性延迟特定于每个体系结构.每个SM子分区和SM都有其他执行单元,包括加载/存储单元,双精度浮点单元,半精度浮点单元,分支单元等.
我推荐这篇文章。它有点过时了,但我认为这是一个很好的起点。本文针对的是开普勒架构,因此最新的 Pascal 架构的行为可能存在一些差异。
您的具体问题的答案(基于文章):
Q1. 块中的线程只有在块中的所有线程运行完毕后才释放其资源吗?
是的。当同一块中的其他 warp 尚未运行时完成运行的 warp 仍会获取其资源,例如寄存器和共享内存。
Q2。当一个block中的所有线程都挂掉后,还会占用资源吗?或者,新的线程块是否会接管资源?
你问的是一个块是否可以被抢占。我通过网络搜索并从这里得到了答案。
在计算能力 < 3.2 的块上永远不会被抢占。在计算能力 3.2+ 上,块可以被抢占的唯一两个实例是在设备端内核启动(动态并行性)或单 GPU 调试期间。
因此,当某些全局内存访问停滞时,块不会放弃其资源。您不应期望停滞的扭曲被抢占,而应设计 CUDA 代码,以便 SM 中驻留大量扭曲,等待调度。在这种情况下,即使某些扭曲正在等待全局内存访问完成,调度程序也可以启动其他线程,从而有效地隐藏延迟。