GPU的内核介绍与运行

前言

要了解GPU执行内核,我们首先需要了解什么是内核及其配置。接下来我们将一步步深入解析。

CUDA内核和线程块简介

CUDA是Nvidia提供的编程接口,用于为其GPU编写程序。在CUDA中,你可以用类似于C/C++函数的形式来表达你想要在GPU上运行的计算,这个函数被称为内核。内核对作为函数参数提供给它的数字向量进行并行操作。一个简单的例子是执行向量加法的内核,即,一个内核,它将两个数字向量作为输入,将它们逐元素相加,并将结果写入第三个向量。 

要在GPU上执行内核,我们需要启动多个线程,这些线程统称为网格。但是网格有更多的结构。网格由一个或多个线程块(有时简称为块)组成,每个块由一个或多个线程组成。

块和线程的数量取决于数据的大小和我们想要的并行度。例如,在我们的向量加法示例中,如果我们正在添加维度为256的向量,则我们可以决定配置256个线程的单个线程块,以便每个线程对向量的一个元素进行操作。对于更大的问题,我们可能没有足够的线程在GPU上,我们可能希望每个线程处理多个数据点。

就实现而言,编写内核需要两个部分。一个是在CPU上执行的主机代码。这是我们加载数据,在GPU上分配内存,并使用配置的线程网格启动内核的地方。第二部分是编写在GPU上执行的设备(GPU)代码。

在GPU上执行内核的步骤

1.将数据从主机传输到设备

在内核可以被调度执行之前,它需要的所有数据都必须从CPU的内存复制到GPU的全局内存中。不过,在最新的GPU硬件中,也可以使用统一虚拟内存直接从主机内存中读取。

2.SM上线程块的调度

GPU在其内存中拥有所有必要的数据后,它将线程块分配给SM。一个块中的所有线程都由同一个SM同时处理。为了实现这一点,GPU必须在SM上为这些线程留出资源,然后才能开始执行它们。在实践中,可以将多个线程块分配给同一个SM以同时执行。

3.单指令多线程(SIMT)和Warp

我们知道一个块的所有线程都被分配给同一个SM。但在此之后还有另一个层次的线程划分。这些线程被进一步分组为大小为32的线程,这被称为线程束(称为线程束2)并且被分配在一起以在被称为处理块的一组核上执行。

SM通过获取并向所有线程发出相同的指令来一起执行线程束中的所有线程。然后这些线程同时执行该指令,但在数据的不同部分上执行。在我们的向量加法示例中,线程束中的所有线程可能都在执行加法指令,但它们将对向量的不同索引进行操作。

这种线程束的执行模型也被称为单指令多线程(SIMT),因为多个线程执行相同的指令,它类似于CPU中的单指令多数据(SIMD)指令。

4.Warp调度和延迟容差

即使SM中的所有处理块(核心组)都在处理线程束,在任何给定时刻,只有少数处理块在主动执行指令。这是因为SM中可用的执行单元数量有限。

但有些指令需要更长的时间才能完成,导致翘曲等待结果。在这种情况下,SM会让等待中的线程束休眠,并开始执行另一个不需要等待任何东西的线程束。这使GPU能够最大限度地利用所有可用的计算并提供高吞吐量。

零开销调度:由于每个线程束中的每个线程都有自己的一组寄存器,因此SM从执行一个线程束切换到另一个线程束没有开销。这与进程之间的上下文切换在CPU上发生的方式相反。如果一个进程正在等待一个长时间运行的操作,CPU会同时在该核心上调度另一个进程。然而,CPU中的上下文切换是昂贵的,因为CPU需要将寄存器保存到主存储器中,并恢复其他进程的状态。

5.将结果从数据传输到主机内存

最后,当内核的所有线程都完成执行之后,就是将结果复制回主机内存。

以上就是本篇文章的所有内容了,如果还有其他疑问欢迎各位在评论区讨论,我们期待你的留言!

END

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值