cuda-gdb 基础使用指南

news2024/11/25 16:09:47

cuda-gdb 基础使用指南

本文的cuda-gdb的简单入门指导,主要的参考是官方文档.但是原文是英文,又找了腾讯家的文档翻译机器,可惜水平着实一般.如果在使用过程中有更细的要求,可以看文档,本文最后贴出原文的目录,可以自己按图索骥,看看有没有其他的需求.

入门要求

既然是cuda-gdb,那么首先是要求gdb的使用指南,本文并不会涉及到这一块,也就是说默认读者已经基本学习了gdb的使用,如果还不会的这里建议先看b站的视频入门,在看这一篇博客,然后还有问题自行参考官方文档和搜索引擎和new bing.

然后是cuda,这里默认读者已经是cuda入门,所以下文中很多名词不会解释.

文档中特别强调的点

编译

和gdb编译类似,cuda-gdb的程序,需要添加额外的编译选项-g -G

cuda-gdb中在cuda代码中不支持watchpoint

只支持主机端的代码,不支持设备端的代码.

cuda-gdb独有的命令的命名规则

每个新的CUDA命令或选项的前缀是CUDA关键字。

这里要举一个我弄错的例子,那就threads,我在实验的时候查看threads,却发现没办法切换到4以后得线程,实际上切换的却是主机端的线程.

(cuda-gdb) info threads
(cuda-gdb) thread 1

实际上CUDA threads 切换 cuda thread 1使用一下命令

(cuda-gdb) info cuda threads
(cuda-gdb) cuda thread 1

cuda 焦点(cuda focus)

我们都知道cuda的体系下有两套并行体系,逻辑上(kernel block thread)和硬件上(device sm warp lane)的.具体的分析,可以参考原文7.1界.

查看当前的焦点(也就是当前的界面显示是哪一个并行下的所属的地方)可以看

(cuda-gdb) cuda device sm warp lane block thread

block (0,0,0), thread (0,0,0), device 0, sm 0, warp 0, lane 0

(cuda-gdb) cuda kernel block thread

kernel 1, block (0,0,0), thread (0,0,0)

至于切换焦点,可以参考一下

(cuda-gdb) cuda device 0 sm 1 warp 2 lane 3
[Switching focus to CUDA kernel 1, grid 2, block (8,0,0), thread
(67,0,0), device 0, sm 1, warp 2, lane 3]
374 int totalThreads = gridDim.x * blockDim.x;

至于thread和block,切换的时候加括号(),用来区分x,y,z轴

(cuda-gdb) cuda thread (15,0,0)
[Switching focus to CUDA kernel 1, grid 2, block (8,0,0), thread
(15,0,0), device 0, sm 1, warp 0, lane 15]
374 int totalThreads = gridDim.x * blockDim.x;

也支持一起切换block和thread

(cuda-gdb) cuda block 1 thread 3
[Switching focus to CUDA kernel 1, grid 2, block (1,0,0), thread (3,0,0),
device 0, sm 3, warp 0, lane 3]
374 int totalThreads = gridDim.x * blockDim.

具体的列表参考一下原文(10.3):


`devices`  information about all the devices
`sms` information about all the active SMs in the current device
`warps` information about all the active warps in the current SM
`lanes` information about all the active lanes in the current warp
`kernels` information about all the active kernels
`blocks` information about all the active blocks in the current kernel
`threads` information about all the active threads in the current kernel
`launch trace` information about the parent kernels of the kernel in focus
`launch children` information about the kernels launched by the kernels in focus
`contexts` information about all the contexts(上下文环境 这一点具体可以看文档)

cuda-gdb的独特打印

cuda里面某些变量是独有的,因此cuda-gdb文档里面特别强调了地方.比如寄存器,本地内存,共享内存.threadIdx,blockDim

一下案例用来打印共享内存与共享内存中的偏移

(cuda-gdb) print &array
$1 = (@shared int (*)[0]) 0x20
(cuda-gdb) print array[0]@4
$2 = {0, 128, 64, 192}

(cuda-gdb) print *(@shared int*)0x20
$3 = 0
(cuda-gdb) print *(@shared int*)0x24
$4 = 128
(cuda-gdb) print *(@shared int*)0x28
$5 = 64

下面的示例显示了如何访问 内核的输入参数的起始地址

(cuda-gdb) print &data
$6 = (const @global void * const @parameter *) 0x10
(cuda-gdb) print *(@global void * const @parameter *) 0x10
$7 = (@global void * const @parameter) 0x110000<∕>


关于反汇编和寄存器,可以参考源文档.

cuda异常代码

其实这一段我觉得不应该放在本文里面,不过既然原文有就放下来好了,参考一下.

在这里插入图片描述

使用案例

源文档中给了三个案例,第三个是结合openmp的,这里就不给出来,需要的自己参考

案例1 bit reversal

#include <stdio.h>
#include <stdlib.h>

// Simple 8-bit bit reversal Compute test

#define N 256

__global__ void bitreverse(void *data) {
    unsigned int *idata = (unsigned int*)data;
    extern __shared__ int array[];

    array[threadIdx.x] = idata[threadIdx.x];

    array[threadIdx.x] = ((0xf0f0f0f0 & array[threadIdx.x]) >> 4) |
                            ((0x0f0f0f0f & array[threadIdx.x]) << 4);
    array[threadIdx.x] = ((0xcccccccc & array[threadIdx.x]) >> 2) |
                            ((0x33333333 & array[threadIdx.x]) << 2);
    array[threadIdx.x] = ((0xaaaaaaaa & array[threadIdx.x]) >> 1) |
                            ((0x55555555 & array[threadIdx.x]) << 1);

    idata[threadIdx.x] = array[threadIdx.x];
}

int main(void) {
    void *d = NULL; int i;
    unsigned int idata[N], odata[N];

    for (i = 0; i < N; i++)
        idata[i] = (unsigned int)i;

    cudaMalloc((void**)&d, sizeof(int)*N);
    cudaMemcpy(d, idata, sizeof(int)*N,
        cudaMemcpyHostToDevice);

    bitreverse<<<1, N, N*sizeof(int)>>>(d);

    cudaMemcpy(odata, d, sizeof(int)*N,
        cudaMemcpyDeviceToHost);

    for (i = 0; i < N; i++)
        printf("%u -> %u\n", idata[i], odata[i]);

    cudaFree((void*)d);
    return 0;
}

首先编译与运行

$ nvcc -g -G bitreverse.cu -o bitreverse
$ cuda-gdb bitreverse

添加breakpoint并运行

(cuda-gdb) break main
Breakpoint 1 at 0x18e1: file bitreverse.cu, line 25.
(cuda-gdb) break bitreverse
Breakpoint 2 at 0x18a1: file bitreverse.cu, line 8.
(cuda-gdb) break 21
Breakpoint 3 at 0x18ac: file bitreverse.cu, line 21.

(cuda-gdb) run
Starting program: ∕Users∕CUDA_User1∕docs∕bitreverse
Reading symbols for shared libraries
..++........................................................... done
Breakpoint 1, main () at bitreverse.cu:25
25 void *d = NULL; int i;

我们继续执行,这里回到核函数里面

(cuda-gdb) continue
Continuing.
Reading symbols for shared libraries .. done
Reading symbols for shared libraries .. done
[Context Create of context 0x80f200 on Device 0]
[Launch of CUDA Kernel 0 (bitreverse<<<(1,1,1),(256,1,1)>>>) on Device 0]
Breakpoint 3 at 0x8667b8: file bitreverse.cu, line 21.
[Switching focus to CUDA kernel 0, grid 1, block (0,0,0), thread (0,0,0), device
,→0, sm 0, warp 0, lane 0]
Breakpoint 2, bitreverse<<<(1,1,1),(256,1,1)>>> (data=0x110000) at bitreverse.cu:9
9 unsigned int *idata = (unsigned int*)data;

现在我们切换观察

在这里插入图片描述

我们现在打印threadid和blockdim

(cuda-gdb) print blockIdx
$1 = {x = 0, y = 0}
(cuda-gdb) print threadIdx
$2 = {x = 0, y = 0, z = 0)
(cuda-gdb) print gridDim
$3 = {x = 1, y = 1}
(cuda-gdb) print blockDim
$4 = {x = 256, y = 1, z = 1)

继续运行并且打印一些函数
在这里插入图片描述

删除观测点并退出

(cuda-gdb) delete breakpoints
Delete all breakpoints? (y or n) y
(cuda-gdb) continue
Continuing.
Program exited normally.
(cuda-gdb)

案例2 单步执行

#define NUM_BLOCKS 8
#define THREADS_PER_BLOCK 64

__global__ void example(int **data) {
    int value1, value2, value3, value4, value5;
    int idx1, idx2, idx3;

    idx1 = blockIdx.x * blockDim.x;
    idx2 = threadIdx.x;
    idx3 = idx1 + idx2;
    value1 = *(data[idx1]);
    value2 = *(data[idx2]);
    value3 = value1 + value2;
    value4 = value1 * value2;
    value5 = value3 + value4;
    *(data[idx3]) = value5;
    *(data[idx1]) = value3;
    *(data[idx2]) = value4;
    idx1 = idx2 = idx3 = 0;
}

int main(int argc, char *argv[]) {
    int *host_data[NUM_BLOCKS * THREADS_PER_BLOCK];
    int **dev_data;
    const int zero = 0;

/* Allocate an integer for each thread in each block */
    for (int block = 0; block < NUM_BLOCKS; block++) {
        for (int thread = 0; thread < THREADS_PER_BLOCK; thread++) {
            int idx = thread + block * THREADS_PER_BLOCK;
            cudaMalloc(&host_data[idx], sizeof(int));
            cudaMemcpy(host_data[idx], &zero, sizeof(int),
            cudaMemcpyHostToDevice);
        }
    }

    /* This inserts an error into block 3, thread 39*/
    host_data[3*THREADS_PER_BLOCK + 39] = NULL;

    /* Copy the array of pointers to the device */
    cudaMalloc((void**)&dev_data, sizeof(host_data));
    cudaMemcpy(dev_data, host_data, sizeof(host_data), cudaMemcpyHostToDevice);

    /* Execute example */
    example <<< NUM_BLOCKS, THREADS_PER_BLOCK >>> (dev_data);
    cudaThreadSynchronize();
}

摆烂了,自己看原文在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GDOUCTF2023 Reverse题解

文章目录题目附件Check_Your_LuckTEA基本逻辑:show函数setKey函数encode函数(tea算法):judge函数解题脚本doublegamesnakefun迷宫关键循环题目附件 链接&#xff1a;https://pan.baidu.com/s/1W0GisS4R-rHYHK4Bu167_g?pwdnw4c Check_Your_Luck 可以看到五条方程,根据方程可…

Flutter开发日常练习-小猫咪杂货店

贴三张效果图 1.欢迎页面 2.商品展示列表 3.购物车页面 因为数据是本地的所以创建本地数据 final List _shopItems [["ZaoShui.", "25.00", "assets/8b10de68e58cfef6bd5f22e5321537.jpg", Colors.green],["ZaoQi.", "25.0…

Unity --- 枪类与子弹类的设计初探 与 Physics Material

1.类的设计方法 --- 首先将不同的对象相同的行为和方法做到一个类A中&#xff0c;然后再给每个对象各创建一个类&#xff0c;并且都继承大类A&#xff0c;同时在自己的类中创建自己独有的方法或者属性 1.一般子弹的射击都是用射线检测的方式去做的 --- 用碰撞器会出现我们不想要…

STM32-高级定时器输出比较模式实验

比较输出功能&#xff1a;定时器通过对预设的比较值与定时器特定寄存器的值做比较之后&#xff0c;并依据相应的输出模式从而实现各类输出&#xff0c;如PWM输出、电平翻转、单脉冲模式等。一般来说&#xff0c;STM32的通用定时器和高级定时器都具有比较输出功能&#xff0c;不…

使用putty在云服务器上安装jdk

在云服务器上安装jdk的步骤&#xff1a; 1. 登录到云服务器&#xff0c;打开putty终端&#xff0c;并使用root账户登录。 2. 在终端中输入以下命令&#xff0c;更新软件包列表&#xff1a; sudo apt-get update 3. 安装OpenJDK 8&#xff0c;请在终端中输入以下命令&#…

leetcode-1041. 困于环中的机器人

leetcode-1041. 困于环中的机器人1. 算法题目2 . 实现思路3. 参考代码1. 算法题目 题目如下&#xff1a; 在无限的平面上&#xff0c;机器人最初位于 (0, 0) 处&#xff0c;面朝北方。注意: 北方向 是y轴的正方向。南方向 是y轴的负方向。东方向 是x轴的正方向。西方向 是x轴的…

Level_2(2)题目整理

文章目录L2-022 重排链表&#xff08;模拟❗&#xff09;L2-023 图着色问题L2-024 部落(并查集)L2-025 分而治之&#xff08;与 L2-023差不多&#xff0c;邻接表遍历&#xff09;L2-026 小字辈&#xff08;求树的深度&#xff09;L2-027 名人堂与代金券(&#x1f4a1;处理&…

统信 UOS 20 初体验

统信 UOS 20 初体验1、下载UOS 202、安装UOS 202.1、发行版选择debian 10 64位2.2、选择Graphic2.3、语言中文2.4、开始安装2.5、安装完后重启2.6、登录UOS 206、使用UOS6.1、包管理器1、下载UOS 20 下载的是服务器免费授权版 https://www.chinauos.com/resource/download-ser…

[Java]面向对象高级篇

文章目录包装类包装类层次结构基本类型包装类特殊包装类数组一维数组多维数组可变长参数字符串String类StringBuilder类内部类成员内部类静态内部类局部内部类匿名内部类Lambda表达式方法引用异常机制自定义异常抛出异常异常的处理常用工具类数学工具类随机数数组工具类包装类 …

【AIGC】Visual ChatGPT 视觉模型深度解析

欢迎关注【youcans的AGI学习笔记】原创作品 【AIGC】Visual ChatGPT 视觉模型深度解析1. 【Visual- ChatGPT】火热来袭2. 【Visual-GPT】操作实例2.1 处理流程2.2 操作实例3. 【Visual-GPT】技术原理分析3.1 技术原理3.2 系统架构3.3 模块说明3.4 Prompt Manager 功能与规则3.5…

Distilling Knowledge via Knowledge Review(引言翻译)

翻译得可能不太准确&#xff0c;希望有能力的各位批评指正&#xff01; Introduction 第一段 深度卷积神经网络&#xff08;CNN&#xff09;在计算机视觉多数任务中取得了显著的成功。 然而&#xff0c;卷积网络的成功往往伴随着相当大的计算和内存消耗&#xff0c; 使得将…

人工智能交互系统界面设计(Tkinter界面设计)

文章目录前言一、项目介绍二、项目准备三、项目实施1.导入相关库文件2.人脸信息验证功能3.语音交互与TCP数据通信4.数据信息可视化四、相关附件前言 在现代信息化时代&#xff0c;图形化用户界面&#xff08;Graphical User Interface, GUI&#xff09;已经成为各种软件应用和…

SpringBoot——Scheduled定时任务

目录 1.静态定时任务 2.动态定时任务 在一些业务场景中&#xff0c;我们需要定义一些任务在我们指定的时间或是每隔一个时间段就自动执行&#xff0c;来作为任务的前提&#xff0c;保证业务的执行。比如&#xff1a;我们需要一个定时任务&#xff0c;每天早上6点执行&#xf…

【springcloud 微服务】Spring Cloud Alibaba Nacos使用详解

目录 一、前言 二、nacos介绍 2.1 什么是 Nacos 2.2 nacos 核心能力 2.2.1 服务发现和服务健康监测 2.2.2 动态配置服务 2.2.3 动态 DNS 服务 2.2.4 服务及其元数据管理 2.2.5 nacos生态地图 2.3 与其他配置中心对比 三、nacos快速部署 3.1 获取安装包 3.2 修改脚…

【分享NVIDIA GTC 23大会干货】加速生成式AI在生物学和医疗领域的应用

【分享NVIDIA GTC 23大会干货】加速生成式AI在生物学和医疗领域的应用1. NVIDIA医疗领域AI计算平台——NVIDIA CLARA2. NVIDIA CLARA医学影像子平台——MONAI3. NVIDIA CLARA医疗设备子平台——Holoscan4. NVIDIA基因组学解决方案Parabricks5. NVIDIA药物研发解决方案6. 个人思…

互联网医院源码|互联网医院软件体现智慧医疗的优势

现在大家看病一般都会直接在互联网医院平台上去就诊&#xff0c;每次大家需要看病时&#xff0c;可以在手机上直接去预约指定的医生&#xff0c;同城周边的所有医院都是可以去直接选择的&#xff0c;这样也可以去帮助大家节省很多的看病时间&#xff0c;在互联网医院软件中所具…

【ApiPost】实现【gRPC】调试【上手篇】

ApiPost下载地址 下载中心-Apipost-中文版接口调试与文档管理工具Apipost官方下载中心为您提供Apipost软件最新版本,其中包括Windows、Mac、Linux等多个客户端的安装包&#xff0c;Apipost下载就上Apipost.cn&#xff0c;国内专业的接口测试软件,一键生成API文档。https://www…

中核科技:科技匠心 智启未来

​  2023 年4月 13—15 日&#xff0c;2023年易派客工业品展览会、石油石化工业展览会、第七届中国石油和化工行业采购年会&#xff0c;在苏州国际博览中心胜利召开。本次展会展览面积53000平方米&#xff0c;参展企业500余家&#xff0c;汇集了中国工业制造领域的大型国企央…

Parcel 实践指南

Parcel 是一个极速零配置的 Web 应用程序打包器。它的零配置特性使得开发者可以更快速地进行项目的构建。本文将向你展示如何在项目中实践 Parcel&#xff0c;并讨论一些性能优化策略以及不同场景下的最佳实践。 总结 Parcel 是一个强大而灵活的打包工具&#xff0c;它可以让你…

【Python_Scrapy学习笔记(八)】基于Scrapy框架实现多级页面数据抓取

基于Scrapy框架实现多级页面数据抓取 前言 本文中介绍 如何基于 Scrapy 框架实现多级页面数据的抓取&#xff0c;并以抓取汽车之家二手车数据为例进行讲解。 正文 在介绍如何基于 Scrapy 框架实现多级页面数据的抓取之前&#xff0c;先介绍下 Scrapy 框架的请求对象 reques…