gpu 内核在完成一个任务后会切换任务吗?

Do gpu cores switch tasks when they're done with one?

我正在试验 C++ AMP,MS 文档中有一点不清楚:

如果我分派一个范围为 1000 的 parallel_for_each,那么这意味着它会产生 1000 个线程。如果 gpu 无法同时处理这 1000 个线程,它会一次完成 300 个或 400 个或它可以完成的任何数量。然后在经纱和瓷砖上有一些模糊的东西,我从中得到了这样的印象:

无论线程如何平铺在一起(或根本不平铺),整个组都必须在执行新任务之前完成,因此如果内部分配的组的大小为 128,其中 30 个完成,则 30 个核心将闲置直到其他 98 个也完成。真的吗?另外,我如何找出这个内部组的大小?

在我的实验过程中,它似乎确实有一定道理,因为为线程分配更均匀的工作量似乎可以加快速度,即使总体工作量稍微多一点。

我想弄清楚的原因是因为我正在决定是否进行另一个冗长的实验,该实验将基于线程获得不均匀的工作量(有时是 10 倍)但是所有线程都是独立的,因此在数据方面,内核可以自由选择另一个线程。

GPU当然不会运行1000个线程同时,但也不会一次完成300个。

它使用多线程,这意味着就像在 CPU 中一样,它将在 1000 个线程中共享 运行 时间,使它们能够完成 看似 同时

请记住,出于多种原因,创建大量线程可能并不有趣。例如,如果您必须在执行第 2 步之前完成第 1 步中的所有 1000 个任务,那么您也可以将它们分配到与 GPU 中的核心数量相等且不超过此数量的线程上。

只有当您想分派没有等待的任务,或者因为您觉得以这种方式编写代码更容易时,使用比内核数量更多的线程才有意义。但请记住,线程管理也很耗时,可能会降低您的性能。

在实践中,AMP在GPU上的底层执行模型与CUDA、OpenCL、Compute Shaders等是相同的,唯一不同的是每个概念的命名。因此,如果您觉得缺少 AMP 文档,请考虑阅读 CUDA 或 OpenCL。这些 API 成熟得多,您从中获得的知识也适用于 AMP。


If I dispatch a parallel_for_each with an extent of say 1000, then that would mean that it spawns 1000 threads. If the gpu is unable to take on those 1000 threads at the same time, it completes them 300 at a time or 400 or whatever number it can do.

也许吧。从parallel_for_each的高层次来看,你不必关心这个。线程也可以按顺序执行,一次一个。

如果您启动 1000 个线程而未指定磁贴大小,AMP 运行time 将根据底层硬件为您选择磁贴大小。如果您指定图块大小,AMP 将使用该图块大小。

GPU 由 多处理器(用 CUDA 的说法,或 计算单元 在 OpenCL 中)组成,每个处理器由许多 核心.

块按多处理器分配:同一个块内的所有线程将由同一个多处理器 运行,直到该块内的所有线程 运行 完成。然后,多处理器将选择另一个可用的图块(如果有的话)并运行它,直到所有图块都被执行。多处理器可以同时执行多个图块。

if the internally assigned group has the size of 128 and 30 of them finish, the 30 cores will idle until the other 98 are done too. Is that true?

不一定。如前所述,多处理器可能有多个活动块。因此,它可能会安排来自其他磁贴的线程保持忙碌。

Important note: On GPU, threads are not executed on a granularity of 1. For example, NVIDIA hardware executes 32 threads at once.

为了避免让这个答案不必要地冗长,我鼓励您阅读 warp 的概念。