20

好的,我知道相关问题已经被一遍又一遍地提出,我阅读了几乎所有我发现的关于此的内容,但事情仍然不清楚。可能也是因为我发现并阅读了相互矛盾的东西(可能是因为来自不同的时代,他们提到了具有不同计算能力的设备,它们之间似乎有很大的差距)。我希望提高效率,以减少我的执行时间,因此我需要确切地知道有多少线程/warp/blocks 可以同时并行运行。此外,我正在考虑对此进行概括,并仅根据我知道我必须执行的操作数量(对于更简单的程序)和系统规范来计算要传递给我的内核的线程和块的最佳数量。

我有一个 GTX 550Ti,顺便说一句,计算能力为 2.1。4 个 SM x 48 个内核 = 192 个 CUDA 内核。

好的,所以我不清楚的是:

可以在多处理器 (SM) 上一次(并行)运行 1 个以上的块吗?我读到最多可以将 8 个块分配给一个 SM,但没有关于它们是如何运行的。从我每个 SM 的最大线程数(1536)几乎不大于我每个块的最大线程数(1024)这一事实,我认为这些块不是并行运行的(可能是 1 个半?)。或者如果我有最大数量的线程,至少不会。此外,如果我将块数设置为 4(我的 SM 数),它们会分别发送到不同的 SM 吗?或者我无法真正控制所有这些在硬件上的分布方式,然后这是一个有争议的问题,我的执行时间将根据我的设备的突发奇想而有所不同......

其次,我知道一个块会将它的线程分成并行运行的 32 个线程组,称为 warp。现在这些扭曲(假设它们彼此没有关系)也可以并行运行?因为在 Fermi 架构中,它声明 2 个 warp 是同时执行的,从每个 warp 发送一条指令到一组 16 个(?)核心,而在其他地方我读到每个核心处理一个 warp,这可以解释 1536 个最大线程( 32 * 48)但似乎有点多。1 个 CUDA 内核可以同时处理 32 个线程吗?

更简单地说,我要问的是:(例如)如果我想在第三个向量中求和 2 个向量,我应该给它们多长(操作数)以及我应该如何将它们分成块和线程我的设备以满容量同时(并行)工作(没有空闲内核或 SM)。

很抱歉,如果之前有人问过这个问题,但我没有得到它或没有看到它。希望您能够帮助我。谢谢!

4

3 回答 3

18

工作的分布和并行执行由启动配置和设备决定。启动配置说明了网格尺寸、块尺寸、每个线程的寄存器和每个块的共享内存。根据此信息和设备,您可以确定可以在设备上同时执行的块和扭曲的数量。在开发内核时,您通常会查看 SM 上可以活动的 warp 与设备的每个 SM 的最大 warp 数的比率。这称为理论占用率。CUDA 占用计算器可用于研究不同的启动配置。

当网格启动时,计算工作分配器将栅格化网格并将线程块分配给 SM,并且将为线程块分配 SM 资源。如果 SM 有足够的资源,可以在 SM 上同时执行多个线程块。

为了启动warp,SM将warp分配给warp调度器并为warp分配寄存器。此时,经线被认为是活动经线。

每个 warp 调度器管理一组 warp(Fermi 上 24 个,Kepler 上 16 个)。未停止的经线称为合格经线。在每个周期,warp 调度程序选择一个合格的 warp 并将该 warp 的指令发送到执行单元,例如 int/fp 单元、双精度浮点单元、特殊功能单元、分支解析单元和加载存储单元。执行单元是流水线的,允许许多 warp 每个周期有 1 条或更多条指令在运行。Warp 可以在指令获取、数据依赖、执行依赖、屏障等上停止。

每个内核都有不同的最佳启动配置。Nsight Visual Studio Edition 和 NVIDIA Visual Profiler 等工具可以帮助您调整启动配置。我建议您尝试以灵活的方式编写代码,以便您可以尝试多种启动配置。我将首先使用一个配置至少 50% 的占用率,然后尝试增加和减少占用率。

每个问题的答案

问:在多处理器 (SM) 上可以同时运行 1 个以上的块(并行)吗?

是的,最大数量取决于设备的计算能力。请参见表 10。 每个计算能力的技术规格:每个多处理器的最大居民块数以确定该值。通常,启动配置会限制运行时间值。有关更多详细信息,请参阅占用计算器或其中一种 NVIDIA 分析工具。

问:从我每个 SM 的最大线程数(1536)几乎不大于我每个块的最大线程数(1024)这一事实,我认为这些块不是并行运行的(可能是 1 个半?)。

启动配置决定了每个 SM 的块数。设置每个块的最大线程数与每个 SM 的最大线程数之比,以允许开发人员在分区工作方式上具有更大的灵活性。

问:如果我将块数设置为 4(我的 SM 数),它们会分别发送到不同的 SM 吗?或者我无法真正控制所有这些在硬件上的分布方式,然后这是一个有争议的问题,我的执行时间将根据我的设备的突发奇想而有所不同......

您对工作分配的控制有限。您可以通过分配更多共享内存来限制占用来人为地控制它,但这是一种高级优化。

问:其次,我知道一个块会将它的线程分成并行运行的 32 个线程组,称为 warp。现在这些扭曲(假设它们彼此没有关系)也可以并行运行吗?

是的,warp 可以并行运行。

问:因为在 Fermi 架构中,它声明 2 个 warp 是同时执行的

每个 Fermi SM 有 2 个 warp 调度器。每个 warp 调度程序可以在每个周期调度 1 个 warp 的指令。指令执行是流水线的,因此许多扭曲每个周期可以有 1 条或更多条指令在运行。

问:从每个扭曲向一组 16 个(?)核心发送一条指令,而在其他地方我读到每个核心处理一个扭曲,这可以解释 1536 个最大线程(32x48)但似乎有点多。1 个 CUDA 内核可以同时处理 32 个线程吗?

是的。CUDA cores 是整数和浮点执行单元的数量。SM 有我上面列出的其他类型的执行单元。GTX550 是 CC 2.1 设备。在每个周期,一个 SM 有可能在每个周期最多分派 4 条指令(128 个线程)。根据执行的定义,每个周期运行的线程总数可以从数百到数千不等。

于 2013-03-23T19:42:02.043 回答
1

我希望提高效率,以减少我的执行时间,因此我需要确切地知道有多少线程/warp/blocks 可以同时并行运行。

简而言之,可以同时运行的线程/扭曲/块的数量取决于几个因素。CUDA C 最佳实践指南有一篇关于执行配置优化的文章,解释了这些因素,并提供了一些关于如何塑造应用程序的推理技巧。

于 2013-03-23T18:21:39.887 回答
-2

对我来说,需要一段时间才能理解的概念之一是 CUDA 芯片上对上下文切换的硬件支持的效率。

因此,每次内存访问都会发生上下文切换,允许计算在许多上下文中交替进行,而其他上下文则在等待内存访问。GPGPU 架构实现性能的方法之一是能够以这种方式并行化,除了在多个内核上并行化。

当没有内核等待内存访问时,可以获得最佳性能,并且通过有足够的上下文来确保这种情况发生。

于 2013-03-20T15:10:29.867 回答