[CUDA 学习笔记] CUDA kernel 的 grid_size 和 block_size 选择

news/2024/11/30 13:42:35/

CUDA kernel 的 grid_size 和 block_size 选择

核函数执行配置

Execution Configuration

cuda_kernel<<< Dg, Db, Ns, S >>>(...)
  • Dg: grid 的维度和大小 (grid_size). 类型 dim3. : Dg.x * Dg.y * Dg.z 为启动的线程块(block)数.
  • Db: 每个线程块的维度和大小 (block_size). 类型 dim3. Db.x * Db.y * Db.z 为每个线程块的线程数.
  • Ns: 每个线程块需动态分配的共享内存的字节数. 类型 size_t. 默认值 0.
  • S: 指定的相关联的 CUDA 流. 类型 cudaStream_t. 默认值 0.

block_size 选择

NVIDIA GPU 算力及规格参数

  • 大于 0, 上限为 1024

  • x 维度和 y 维度上限 1024, z 维度上限 64

  • 最好是 32 的倍数. 因为一个 warp 有 32 个线程.

  • 最好是不小于 SM 上最大同时执行的线程数(Maximum number of resident threads per SM)和最大同时执行的线程块数(Maximum number of resident blocks per SM)的比值.
    因为要尽可能让 GPU 占有率(Occupancy, SM 上并发执行的线程数和 SM 上最大支持的线程数的比值)达到 100%, 所以

    S M 理论线程数 = b l o c k _ s i z e × S M 最大 b l o c k 数 ≥ S M 最大线程数 ⇒ b l o c k _ s i z e ≥ S M 最大线程数 / S M 最大 b l o c k 数 \begin{aligned} & SM理论线程数=block\_size\times SM最大block数\geq SM最大线程数\\ &\Rightarrow \ block\_size \geq SM最大线程数/SM最大block数 \end{aligned} SM理论线程数=block_size×SM最大blockSM最大线程数 block_sizeSM最大线程数/SM最大block
    V100 、 A100、 GTX 1080 Ti 为 2048 / 32 = 64, RTX 3090 为 1536 / 16 = 96. 因此 block_size 不应小于 96.

  • 最好是 SM 最大线程数的约数(因数). 因为 block 调度到 SM 的过程是原子的, 即该 block 中的所有线程都在同一 SM 上执行, 因此 block_size 为 SM 最大线程数的约数时可以确保 SM 不会有一直空闲的线程.
    主流架构最大线程数(2048, 1536, 1024)的公约数为 512, 256, 128.

  • 寄存器、共享内存等资源对应到每个线程不能超过上限(每个 block 的 32 位寄存器数量, 每个 block 的共享内存大小上限). 这里指明为"对应到每个线程", 即每个线程所使用的寄存器数、共享内存应小于上限/ block_size.

在不考虑线程同步等其他因素的情况下:

  • 当寄存器和共享内存使用较少时, 可以将 block_size 设置为较大的 512、1024(SM 最大线程数不为 1536 时);
  • 反之, 当寄存器和共享内存使用较多时, 可以将 block_size 设置的较小, 即 128、256.
  • ※ 在笔者接触的一些 CUDA 库中, block_size 一般多被设置为 128、256

grid_size 选择

  • x 维度上限 231-1, y 维度和 z 维度上限 65535.
  • 不应低于 GPU 上 SM 的数量 (A100 为 108 个). 因为至少让每个 SM 都启动 1 个 block
  • 最好不低于 S M 数 × 每个 S M 最大 b l o c k 数 SM数\times 每个SM最大block数 SM×每个SM最大block. 这样一批 GPU 可以一次几乎同时完成的 block 称之为 wave, 这里的"每个 SM 最大 block 数"根据实际情况会不同.
  • 数量足够多的整数个 wave, 或数量足够大. 考虑到 GPU 的多 CUDA 流等情况, 仍可能出现尾效应(tail effect, 一个 wave 完成后, GPU 上将只有很少的 block 在执行), 因此 grid_size 足够大可以让 GPU 尽可能充分调度运行.

如下是 Oneflow 中的计算方式:

unsigned grid_size = std::max<int>(1, std::min<int64_t>((n + kBlockSize - 1) / kBlockSize,sm_count * tpm / kBlockSize * kNumWaves));
  • n: 数据个数
  • kBlockSize: block_size
  • sm_count: SM 个数
  • tpm: SM 上最大同时执行的线程数(Maximum number of resident blocks per SM)
  • kNumWaves: wave 个数(上文有提到), 一般设置为 32. 使 grid 为整数个 wave.

数据量较小的情况下, 不会启动过多的线程块 ((n + kBlockSize - 1) / kBlockSize); 在数据量较大的情况下, 尽可能将线程块数目设置为数量足够多的整数个 wave, 以保证 GPU 实际利用率够高 (sm_count * tpm / kBlockSize * kNumWaves).

参考资料

  • 如何设置CUDA Kernel中的grid_size和block_size? - 知乎
  • 高效、易用、可拓展我全都要:OneFlow CUDA Elementwise 模板库的设计优化思路 - 知乎

http://www.ppmy.cn/news/1327356.html

相关文章

LeetCode 2788.按分隔符拆分字符串:模拟(字符串处理)

【LetMeFly】2788.按分隔符拆分字符串&#xff1a;模拟&#xff08;字符串处理&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/split-strings-by-separator/ 给你一个字符串数组 words 和一个字符 separator &#xff0c;请你按 separator 拆分 words 中…

E - Sugoroku 3(数学期望)

思路&#xff1a;数学推导过程 代码&#xff1a; const long long mod998244353; int n; inline int qmi(int x,int y){int z1;for(;y;y>>1,xx*x%mod)if(y&1)zz*x%mod;return z; }void solve(){cin>>n;vector<int>a(n2),sum(n2),dp(n2);for(int i1;i&l…

系统架构的演变:从单体到微服务的旅程

文章目录 前言一、单体架构简图 二、垂直架构简图 三、水平架构简图 四、面向服务架构&#xff08;SOA&#xff09;简图 五、微服务架构简图 总结 前言 随着信息技术的快速发展&#xff0c;系统架构也在不断演变。从早期的单体架构到现代的微服务架构&#xff0c;每一次的变革都…

Unity下实现跨平台的RTMP推流|轻量级RTSP服务|RTMP播放|RTSP播放低延迟解决方案

2018年&#xff0c;我们开始在原生RTSP|RTMP直播播放器的基础上&#xff0c;对接了Unity环境下的低延迟播放&#xff0c;毫秒级延迟&#xff0c;发布后&#xff0c;就得到了业内一致的认可。然后我们覆盖了Windows、Android、iOS、Linux的RTMP推送、轻量级RTSP服务和RTSP|RTMP播…

Opencv4快速入门笔记

opencv4 一、数据载入显示和储存 1.Mat类 cv::Mat a(640,480,CN_8UC3); //640*480 3通道 cv::Mat a(Size(480,640),CV_8UC1); Mat m a.clone();//克隆 Mat b (a,Range(2,5),Range(3,5));//截取a中2-5行&#xff0c;3-5列 Mat b(2,2,CV_8UC3,Scalar(0,0,255));//构造时赋值…

WordPress设置回收站自动清理天数的插件Change Empty Trash Time

前面boke112百科跟大家分享的『WordPress回收站自动清空时间&#xff1f;如何关闭回收站或设置自动清理天数&#xff1f;』一文&#xff0c;就介绍了可以添加一行代码实现关闭或设置回收站自动清理时间&#xff0c;也可以通过安装Change Empty Trash Time插件来实现。 今天bok…

第八回 柴进门招天下客 林冲棒打洪教头-Linux服务器管理软件宝塔面板介绍

花和尚鲁智深在野猪林救下了豹子头林冲&#xff0c;林冲宅心人厚&#xff0c;反而恳请鲁智深饶过薛霸与董超的性命。鲁智深劝不动林冲跟他一起逃走&#xff0c;只好一路护送至沧州附近才离开。 快到沧州时&#xff0c;林冲来到小旋风柴进府上&#xff0c;受到热情款待。柴进府…

爬虫逆向开发教程1-介绍,入门案例

爬虫前景 在互联网的世界里&#xff0c;数据就是新时代的“黄金”。而爬虫&#xff0c;就是帮助我们淘金的“工具”。随着互联网的不断发展&#xff0c;数据量呈现指数级的增长&#xff0c;在数据为王的时代&#xff0c;有效的挖掘数据和利用&#xff0c;你会得到更多东西。 学…