问题标签 [warp-scheduler]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
cuda - CUDA 块/扭曲/线程如何映射到 CUDA 内核?
我已经使用CUDA几个星期了,但是我对blocks/warps/thread的分配有些怀疑。 我正在从教学的角度(大学项目)研究架构,因此达到最佳性能不是我关心的问题。
首先,我想了解我是否了解这些事实:
程序员编写内核,并在线程块网格中组织其执行。
每个块都分配给一个流式多处理器 (SM)。一旦分配它就不能迁移到另一个 SM。
每个 SM 将自己的块拆分为 Warps(当前最大大小为 32 个线程)。warp 中的所有线程在 SM 的资源上同时执行。
线程的实际执行由 SM 中包含的 CUDA 核心执行。线程和内核之间没有特定的映射。
如果一个 warp 包含 20 个线程,但当前只有 16 个内核可用,则该 warp 将不会运行。
另一方面,如果一个块包含 48 个线程,它将被分成 2 个 warp,如果有足够的可用内存,它们将并行执行。
如果一个线程在一个内核上启动,那么它会因内存访问或长浮点操作而停止,它的执行可能会在另一个内核上恢复。
他们是正确的吗?
现在,我有一个 GeForce 560 Ti,所以根据规格它配备了 8 个 SM,每个包含 48 个 CUDA 核心(总共 384 个核心)。
我的目标是确保架构的每个核心都执行相同的指令。假设我的代码不需要比每个 SM 中可用的更多的寄存器,我设想了不同的方法:
我创建了 8 个块,每个块有 48 个线程,因此每个 SM 有 1 个块要执行。在这种情况下,48 个线程是否会在 SM 中并行执行(利用所有可用的 48 个内核)?
如果我启动 64 个 6 个线程的块有什么区别吗?(假设它们将在 SM 之间均匀映射)
如果我将 GPU “淹没”在预定的工作中(例如,创建 1024 个块,每个块有 1024 个线程)是否可以合理地假设所有内核都将在某个点使用,并且将执行相同的计算(假设线程永不停止)?
有没有办法使用分析器检查这些情况?
这个东西有参考吗?我阅读了 CUDA 编程指南以及“大规模并行处理器编程”和“CUDA 应用程序设计与开发”中专门针对硬件架构的章节;但我无法得到准确的答案。
cuda - 块,线程,warpSize
关于如何选择#blocks & blockSize 已经有很多讨论,但我仍然遗漏了一些东西。我的许多担忧都解决了这个问题:CUDA Blocks/Warps/Threads 如何映射到 CUDA Cores? (为了简化讨论,有足够的 perThread 和 perBlock 内存。内存限制在这里不是问题。)
1)为了让 SM 尽可能忙碌,我应该设置nThreads
为warpSize
. 真的?
2) 一个 SM 一次只能执行一个内核。也就是说,该 SM 的所有 HWcore 都只执行 kernelA。(不是一些运行 kernelA 的 HWcore,而其他运行 kernelB。)因此,如果我只有一个线程要运行,我将“浪费”其他 HWcore。真的?
3)如果warp-scheduler发出以单位为单位的工作warpSize
,并且每个SM有32个HWcore,那么SM将被充分利用。当 SM 有 48 个 HWcore 时会发生什么?当调度程序以 32 个块的形式发布工作时,如何保持所有 48 个内核的充分利用?(如果上一段是真的,调度器以HWcore大小为单位下发工作不是更好吗?)
4)看起来warp-scheduler一次排队2个任务。因此,当当前执行的内核停止或阻塞时,第二个内核被换入。(不清楚,但我猜这里的队列深度超过 2 个内核。)这是正确的吗?
5) 如果我的硬件的上限为每块 512 个线程 (nThreadsMax),这并不意味着具有 512 个线程的内核将在一个块上运行得最快。(同样,内存不是问题。)如果我将 512 线程内核分布在许多块上,而不仅仅是一个块,我很有可能会获得更好的性能。该块在一个或多个 SM 上执行。真的?
5a)我认为越小越好,但是我做多小有关系nBlocks
吗?问题是,如何选择那个值nBlocks
是体面的?(不一定是最优的。)是否有一种数学方法来选择nBlocks
,或者只是试错法。
cuda - cuda 共享内存和块执行调度
我想清除CUDA 共享内存的执行状态,并根据每个块使用的共享内存量进行 块执行。
状态
我的目标是 GTX480 nvidia 卡,它每块有 48KB共享内存和 15 个流式多处理器。因此,如果我声明一个包含 15 个块的内核,每个块使用 48KB 的共享内存,并且没有达到其他限制(寄存器、每个块的最大线程数等),每个块都运行到一个 SM(15 个)直到结束。在这种情况下,只需要在同一块的 warp 之间进行调度。
问题
所以,我的误解是:
我调用一个有 30 个块的内核,以便每个 SM 上驻留 2 个块。现在每个 SM 上的调度程序必须处理来自不同块的扭曲。但只有当一个块完成执行时,另一个块的扭曲才会在 SM 上执行,因为共享内存总量(每个 SM 48KB)使用。如果这没有发生并且不同块调度在同一个 SM 上执行的扭曲,结果可能是错误的,因为一个块可以读取从另一个块加载到共享内存中的值。我对吗?
cuda - cuda:扭曲发散开销与额外算术
当然,在 GPU 上要不惜一切代价避免扭曲发散、viaif
和语句。switch
但是,warp 发散(仅调度一些线程来执行某些行)与额外的无用算术的开销是多少?
考虑以下虚拟示例:
版本 1:
对比
版本 2:
我的真实情况更复杂(更多条件),但想法相同。
问题:
经线发散的开销(在调度中)是否如此之大以至于版本 1)比版本 2 慢?
版本 2 需要比版本 1 更多的 ALU,其中大部分都浪费在“乘以 0”上(只有少数几个条件计算为 1 而不是 0)。这是否会将有价值的 ALU 捆绑在无用的操作中,从而延迟其他 warp 中的指令?
optimization - CUDA 中 warp 调度程序的指令发布时间延迟是多少?
我的印象是计算能力 1.x GPU 中的(单个)warp 调度程序每 4 个周期每个 warp 发出一条指令,并且由于算术流水线的延迟是 24 个周期,因此可以通过 6 个活动 warp 完全隐藏它在任何时候。
对于计算能力 2.1 GPU,编程指南提到“在每个指令发出时间,每个调度程序都会发出两条独立的指令”,而CUDA warp 调度程序如何一次发出 2 条指令的帖子?建议每个调度程序可以在每个周期的每个 warp 发出一条指令。
那么warp调度程序的确切延迟是多少?每个warp每多少个周期发出一条指令?是否同时向任何活动和准备好的经线发出不同的指令(MIMD)?
cuda - CUDA Kepler:没有足够的 ALU
根据 Kepler 白皮书,基于 Kepler 的 GPU 的 warp 大小为 32,每个多处理器包含 4 个 warp 调度程序,它们从选定的 warp 中选择两个独立的指令。这意味着每个时钟周期要执行 32*4*2 = 256 次计算,但多处理器仅包含 192 个 ALU。那么这些计算是如何进行的呢?
cuda - CUDA 扭曲和线程发散
我试图了解 CUDA 扭曲和线程分歧。假设我有一个简单的矩阵乘法内核来乘以 nxn 矩阵。
如果我启动一个网格大小为 32 x 32 和块大小为 16 x 16 的内核,并且矩阵为 500 x 500,那么有多少线程会遇到线程发散?
既然矩阵右边缘的每个线程块都会有线程发散,那么线程发散的warp数量不应该是256吗?
cuda - 为什么 GPU 的 SM 中有两个 warp 调度器?
我阅读了 NVIDIA Fermi 白皮书,并在计算 SP 内核、调度程序的数量时感到困惑。
根据白皮书,在每个 SM 中,有两个 warp 调度器和两个指令调度单元,允许同时发出和执行两个 warp。一个SM中有32个SP核,每个核都有一个全流水线的ALU和FPU,用于执行一个线程的指令
众所周知,一个warp是由32个线程组成的,如果我们每个周期只发出一个warp,这意味着这个warp中的所有线程将占用所有SP核心,并在一个周期内完成执行(假设没有任何停顿)。
然而,NVIDIA 设计了双调度器,它选择两个 warp,并从每个 warp 向一组十六个内核、十六个加载/存储单元或四个 SFU 发出一条指令。
英伟达表示,这种设计可以带来最高的硬件性能。也许最高的硬件性能来自于不同指令的交错执行,充分利用了硬件资源。
我的问题如下(假设没有内存停顿并且所有操作数都可用):
每个 warp 是否需要两个周期才能完成执行,并且所有 32 个 SP 内核都为每个 warp 调度程序分为两组?
ld/st 和 SFU 单元由所有 warp 共享(对于双调度程序的 warp 来说看起来是统一的)?
如果一个经线分为两部分,首先安排哪一部分?有调度程序吗?或者只是随机选择一个部分来执行。
这种设计的优势是什么?只是最大限度地利用硬件?
cuda - CUDA 的 resident warp 问题
我已经使用 CUDA 一个月了,现在我想弄清楚需要多少扭曲/块来隐藏内存访问的延迟。我认为这与多处理器上的最大常驻扭曲有关。
根据 CUDA_C_Programming_Guide (v-7.5) 中的 Table.13,每个多处理器的驻留扭曲的最大值为 64。那么,我的问题是:什么是驻留扭曲?它是指那些从 GPU 内存读取的数据并准备好由 SP 处理的扭曲吗?或者指可以为数据读取内存的经线或准备好由 SP 处理的经线,这意味着除了这 64 个经线之外的其余经线既不能读取内存也不能被 SP 处理,直到这 64 个常驻经线中的一些完成.
cuda - 有没有办法将线程显式映射到 CUDA 中的特定扭曲?
比如说,动态分析是在一个 CUDA 程序上完成的,这样某些线程最好在同一个 warp 中。
例如,假设我们有 1024 个 cuda 线程,warp 大小为 32。经过动态分析,我们发现线程 989、243、819、...、42(总共列出了 32 个线程)应该在同一个 warp 上。我们确定它们应该在同一个 warp 上,因为它们在代码执行方面几乎没有分歧——(在执行 CUDA 程序的动态分析时,它们可能不一定在同一个 warp 上)。
有没有办法控制线程在 CUDA 中扭曲调度?如果没有,是否有另一种 GPU 编程语言可以提供这种显式的扭曲调度。如果没有,可以做些什么(甚至可能是解决这个问题的非常低级的方法)?我希望至少有最后一个问题的答案,因为这可能是 CUDA 的实现方式——除非在硬件级别完成扭曲调度,这将是不幸的。谢谢!