CUDA内核,流式多处理器与块和线程的CUDA模型之间是什么关系?
什么映射到什么,什么并行化以及如何并行化?还有什么效率更高的方法,那就是最大化块数或线程数?
我目前的理解是每个多处理器有8个cuda内核。并且每个cuda核心将能够一次执行一个cuda块。并且该块中的所有线程都在该特定内核中按顺序执行。
它是否正确?
CUDA内核,流式多处理器与块和线程的CUDA模型之间是什么关系?
什么映射到什么,什么并行化以及如何并行化?还有什么效率更高的方法,那就是最大化块数或线程数?
我目前的理解是每个多处理器有8个cuda内核。并且每个cuda核心将能够一次执行一个cuda块。并且该块中的所有线程都在该特定内核中按顺序执行。
它是否正确?
Answers:
CUDA编程指南中详细描述了线程/块的布局。特别是,第4章指出:
CUDA体系结构围绕可扩展的多线程流多处理器(SM)阵列构建。当主机CPU上的CUDA程序调用内核网格时,将枚举网格的块并将其分发给具有可用执行能力的多处理器。线程块的线程在一个多处理器上同时执行,而多个线程块可以在一个多处理器上同时执行。随着线程块的终止,新的块将在腾出的多处理器上启动。
每个SM包含8个CUDA内核,并且在任何时候它们一次执行32个线程的一次扭曲-因此需要4个时钟周期才能为整个扭曲发出一条指令。您可以假定任何给定扭曲中的线程都以锁步方式执行,但是要在各个扭曲之间进行同步,您需要使用__syncthreads()
。
对于GTX 970,有13个流式多处理器(SM),每个带128个Cuda内核。Cuda核心也称为流处理器(SP)。
您可以定义将块映射到GPU的网格。
您可以定义将线程映射到流处理器的块(每个SM 128个Cuda核心)。
一个扭曲总是由32个线程构成,并且扭曲的所有线程都是同时执行的。
要使用GPU的全部功能,每个SM所需的线程数要比SM拥有的SP多得多。对于每个计算能力,一次可以有一定数量的线程驻留在一个SM中。您定义的所有块都排队,等待SM拥有资源(可用SP数),然后将其加载。SM开始执行扭曲。由于一个Warp仅具有32个线程,而一个SM具有例如128个SP,因此SM可以在给定时间执行4个Warp。问题是,如果线程进行内存访问,则线程将阻塞,直到满足其内存请求为止。数量上:SP上的算术计算有18-22个周期的延迟,而非缓存的全局内存访问最多需要300-400个周期。这意味着,如果一个扭曲的线程正在等待数据,则只有128个SP的子集可以工作。因此,调度程序切换为执行另一个扭曲(如果有)。如果此扭曲阻塞,则执行下一个,依此类推。这个概念称为延迟隐藏。经纱的数量和块大小决定了占用率(SM可以选择执行多少条经纱)。如果占用率很高,则SP不太可能没有工作。
您关于每个cuda内核一次执行一个块的说法是错误的。如果您谈论流多处理器,它们可以从驻留在SM中的所有线程执行扭曲。如果一个块的大小为256个线程,并且您的GPU允许每个SM驻留2048个线程,则每个SM将有8个块驻留,SM可以从中选择要执行的扭曲。执行的线程束的所有线程都是并行执行的。
您可以在此处找到不同计算能力和GPU架构的编号:https: //en.wikipedia.org/wiki/CUDA#Limitations
您可以从Nvidia占用计算表(由Nvidia下载)下载占用计算表。
仅当SM具有足够的线程块资源(共享内存,扭曲,寄存器,屏障等)时,Compute Work Distributor才会在SM上调度线程块(CTA)。线程块级资源(如共享内存)已分配。分配为线程块中的所有线程创建足够的扭曲。资源管理器使用循环机制分配经线将给SM子分区。每个SM子分区都包含一个扭曲调度程序,寄存器文件和执行单元。将扭曲分配给子分区后,它将保留在子分区上,直到完成或被上下文切换(Pascal架构)抢占为止。在上下文切换恢复时,扭曲将恢复为相同的SM相同的扭曲ID。
当warp中的所有线程都已完成时,warp调度程序将等待warp发出的所有未完成指令完成,然后资源管理器将释放warp级别的资源,其中包括warp-id和注册文件。
当线程块中的所有扭曲均完成时,则释放块级资源,并且SM通知Compute Work Distributor该块已完成。
一旦将warp分配给一个子分区并分配了所有资源,就将warp视为活动状态,这意味着warp调度程序正在主动跟踪warp的状态。在每个周期上,翘曲调度程序都会确定哪些活动的翘曲已停止,哪些合格的翘曲有资格发出指令。Warp调度程序会选择优先级最高的合格Warp,并从Warp发出1-2个连续的指令。双重问题的规则特定于每种体系结构。如果warp发出了内存负载,它可以继续执行独立的指令,直到到达相关指令为止。然后,扭曲将报告已停止,直到加载完成。依赖数学指令也是如此。SM体系结构旨在通过在扭曲之间每个周期进行切换来隐藏ALU和内存延迟。
该答案未使用术语CUDA核心,因为这会引入错误的心理模型。CUDA内核是流水线式单精度浮点/整数执行单元。发行率和依赖性等待时间特定于每种体系结构。每个SM子分区和SM都有其他执行单元,包括加载/存储单元,双精度浮点单元,半精度浮点单元,分支单元等。
为了最大化性能,开发人员必须了解块与扭曲与寄存器/线程之间的权衡。
占用率是SM上活动翘曲与最大翘曲的比率。开普勒-Pascal架构(GP100除外)每个SM有4个warp调度程序。每个SM的最小经纱数量应至少等于经纱调度程序的数量。如果架构具有6个周期(麦克斯韦和帕斯卡)的相关执行延迟,则每个调度程序至少需要6个翘曲,每个SM为24(24/64 = 37.5%占用),以弥补延迟。如果线程具有指令级并行性,则可以减少并行度。几乎所有内核都发出可变等待时间指令,例如可能需要80-1000个周期的内存负载。这需要每个warp调度程序更多活动的warp以隐藏延迟。对于每个内核,在扭曲数量和其他资源(例如共享内存或寄存器)之间存在一个折衷点,因此不建议对100%的占用进行优化,因为可能会做出其他牺牲。CUDA探查器可以帮助确定指令的发出率,占用率和停顿原因,以帮助开发人员确定平衡。
线程块的大小会影响性能。如果内核具有大块并使用同步屏障,则屏障停顿可能是一个即将到来的停顿原因。这可以通过减少每个线程块的扭曲来缓解。