当前位置: 首页 > news >正文

【CUDA 】第4章 全局内存——4.4 核函数可达到的带宽(4对角转置)【补图】

CUDA C编程笔记

  • 第四章 全局内存
    • 4.4 核函数可达到的带宽
        • 4.4.2.4 对角转置【为每个线程分配更独立的任务】
  • 【图】
  • 【补图+说明】

待解决的问题:

第四章 全局内存

4.4 核函数可达到的带宽

4.4.2.4 对角转置【为每个线程分配更独立的任务】

前置条件场景:启用线程块的网格时,线程块会被分配给SM。每个块有唯一的标识符bid,可以按行优先的顺序标注:

int bid = blockIdx.y * gridDim.x + blockIdx.x;//块的标识bid

当启用核函数时,线程块的ID决定分配给SM的顺序,如果所有SM都被占用,剩余的线程块等待有SM空余再分配。但由于线程块完成的速度和顺序不确定,因此可能最初相连的bid也会变得不连续。

下图是笛卡尔坐标系(直角)和对角块坐标系下的块标识顺序。

【图】

对角块坐标系用于确定一维线程块的ID,但访问数据时仍用笛卡尔坐标系。

对角坐标————笛卡尔坐标(直角)的转换

(直角坐标)block_x = (blockIdx.x + blockIdx.y) % gridDim.x;【blockIdx.x对角坐标】
(直角坐标)block_y = blockIdx.x;【blockIdx.y对角坐标】

核函数起始部分:对角坐标到直角坐标的映射计算+直角坐标计算线程索引ix、iy
借助合并读取+交叉写入——>实现转置

//3.对角转置————基于行
//①对角坐标系转直角坐标系②直角坐标系算线程索引ix、iy③转置
__global__ void transposeDiagonalRow(float *out, float *in, const int nx, const int ny){
    unsigned int blk_y = blockIdx.x;//blk_y直角坐标系,blockIdx.x对角坐标系
    unsigned int blk_x = (blockIdx.x+blockIdx.y) % gridDim.x;//blk_x直角坐标系,blockIdx.y对角坐标系

    unsigned int ix = blockDim.x * blk_x + threadIdx.x;//用直角坐标算线程索引
    unsigned int iy = blockDim.y * blk_y + threadIdx.y;

    if(ix < nx && iy < ny){
        out[ix*ny + iy] = in[iy*nx + ix];
    }
}

//3.对角转置————基于列
//在基于行的基础上对换in和out的下标
__global__ void transposeDiagonalRow(float *out, float *in, const int nx, const int ny){
    unsigned int blk_y = blockIdx.x;//blk_y直角坐标系,blockIdx.x对角坐标系
    unsigned int blk_x = (blockIdx.x+blockIdx.y) % gridDim.x;//blk_x直角坐标系,blockIdx.y对角坐标系

    unsigned int ix = blockDim.x * blk_x + threadIdx.x;//用直角坐标算线程索引
    unsigned int iy = blockDim.y * blk_y + threadIdx.y;

    if(ix < nx && iy < ny){
        out[iy*nx + ix] = in[ix*ny + iy];
    }
}

        case 6:3.对角转置----基于行
            kernel = &transposeDiagonalRow;
            kernelName = "DiagonalRow       ";
            break;

        case 7:3.对角转置----基于列
            kernel = &transposeDiagonalCol;
            kernelName = "DiagonalCol       ";
            break;

输出结果如下:

~/cudaC/unit4$ ./4-6.1transposeNsys 6 对角转置-基于行
./4-6.1transposeNsys starting transpose at device 0: NVIDIA GeForce RTX 3090 
 with matrix nx 2048 ny 2048 with kernel 6
warmup         elapsed 0.000563 sec
DiagonalRow        elapsed 0.000075 sec <<< grid (128,128) block (16,16)>>> effective bandwidth 448.208557 GB

~/cudaC/unit4$ ./4-6.1transposeNsys 7 对角转置-基于列
./4-6.1transposeNsys starting transpose at device 0: NVIDIA GeForce RTX 3090 
 with matrix nx 2048 ny 2048 with kernel 7
warmup         elapsed 0.000561 sec
DiagonalCol        elapsed 0.000064 sec <<< grid (128,128) block (16,16)>>> effective bandwidth 525.139893 GB

查询可得,理论峰值带宽为936 GB/s
基于行的对角是理论峰值的48%↑
基于列的对角是理论峰值的56%↓

结果:对角使得基于行性能提高↑,但使得基于列下降,基于列还是直角坐标性能好

基于行性能提升的原因:DRAM的并行访问
DRAM分区完成发送给全局内存的请求,设备内存中连续的256字节区域分配到连续的分区。使用直角坐标把线程块映射到——>数据块时,全局内存访问无法均匀分配到整个DRAM分区,发生“分区冲突”:内存请求在部分分区内排队等待,但另一部分分区一直空闲未被调用。
对角坐标映射造成了线程块——>数据块的非线性映射,交叉访问不太可能落到一个独立的分区,这导致速度提升。

最佳性能,一般是(所有活跃warp并发访问的)全局内存被均匀地划分。

【补图+说明】

相关文章:

  • 在 macOS 的 ARM 架构上按住 Command (⌘) + Shift + .(点)。这将暂时显示隐藏文件和文件夹。
  • 动态蛇形卷积在YOLOv8中的探索与实践:提高目标识别与定位精度
  • 【已解决】《Python》[Errno 2] No such file or directory
  • Vue3.x的深度选择器详细解读
  • 网络工程师 (48)传输层概述
  • 【嵌入式Linux应用开发基础】特殊进程
  • 硬编码(一)经典定长指令
  • 用Deepseek查询快证API-物流查询-实名认证-企业实名认证
  • layui 远程搜索下拉选择组件(多选)
  • PCL AlphaShape算法曲面重建
  • 如何查询网站是否被百度蜘蛛收录?
  • 路由基础 | 路由引入实验 | 不同路由引入方式存在的问题
  • CF1801D
  • DateFormat与日期处理
  • CRTP在项目优化中的使用
  • Compose常用UI组件
  • WIN系统服务器如何修改远程端口?
  • Spring Bean 生命周期
  • 14 命令(Command)模式
  • 【STM32H743IIT6】正点原子阿波罗TFTLCD移植
  • 做网站 流量怎么抓钱/引流获客app下载
  • 河北特定网站建设推荐/seo优化网站查询
  • 网站留言系统编写代码/百度推广客户端下载安装
  • 宁波海曙网站开发公司/河南百度seo
  • 家具网站开发任务书/外贸网站哪个比较好
  • 医院网站建设报价/关键词如何快速排名