很多人都知道x86 CPU的断点指令,即著名的INT 3,机器码为0xCC。在Nvidia的GPU中,比如著名的伏特微架构,也有一条断点指令,叫BPT,是Breakpoint的缩写。

那么,在AMD GPU中是否也有这样一条指令呢?

在回答这个问题前,先看一段AMD GPU的指令吧。

s_addc_u32    s17, s17, s19               // 000000000168: 82111311s_lshr_b64    s[16:17], s[16:17], 16        // 00000000016C: 8F909010s_mul_i32     s5, s5, s13                // 000000000170: 92050D05s_add_u32     s5, s5, s16                // 000000000174: 80051005s_mul_i32     s4, s4, s8                // 000000000178: 92040804v_add_u32     v3, vcc, s4, v0             // 00000000017C: 32060004
=>   s_nop         0x0000                  // 000000000180: BF800000s_load_dword  s4, s[6:7], 0x18             // 000000000184: C0020103 00000018s_nop         0x0000                  // 00000000018C: BF800000s_load_dword  s5, s[6:7], 0x40             // 000000000190: C0020143 00000040s_nop         0x0000                 // 000000000198: BF800000s_load_dword  s12, s[6:7], 0x20           // 00000000019C: C0020303 00000020s_nop         0x0000                 // 0000000001A4: BF800000s_load_dword  s13, s[6:7], 0x48            // 0000000001A8: C0020343 00000048s_waitcnt     lgkmcnt(0)                // 0000000001B0: BF8C007Fs_nop         0x0000                // 0000000001B4: BF800000v_add_u32     v9, vcc, s4, v3             // 0000000001B8: 32120604s_nop         0x0000                  // 0000000001BC: BF800000v_add_u32     v13, vcc, s5, v3       // 0000000001C0: 321A0605v_mov_b32     v5, s8                // 0000000001C4: 7E0A0208

AMD的GPGPU已经发展了几轮,比较著名的有Terascale微架构,发展了三代后,被GCN(Graphics Core Next)微架构所取代,GCN已经发展了6代,预计2020年退役。

上面这段汇编代码就是GCN微架构的指令。

GCN的指令是从Terascale的VLIW指令演变而来的。VLIW的字面意思就是“非常长的指令字”。不过GCN的指令已经不再是VLIW风格。不仅指令的长度不是那么长了(32或者64位),更重要的是每条指令的操作都是针对当前算核的单一数据项,操作比较单纯,不再强调指令级别的并行。

上面清单右侧注释部分就是指令的机器码。可以看到大多数是32位,个别是64位。

GCN指令有一个非常大的特色,那就是把所有操作分为标量和向量两个大类。上面s_开头的都是标量指令,v_开头的都是向量指令。在GPU内部,标量指令会送给标量ALU(sALU)来执行,向量指令会送给向量ALU执行(vALU)。AMD GPU也有与Nvidia的WARP相同的概念,叫wavefront。每个wavefront是64个线程。考虑到在每个算核(kernel)的开头结尾,以及某些逻辑部分常常只需要一个处理器执行,比如对于上面的那么多条s_指令,就只要一个sALU执行就可以了,不需要浪费vALU,因为vALU一行动,就是64个一排碾压过去。这样考虑,AMD的设计是非常聪明的。

再回头来说断点指令。浏览GCN的指令集,没有专门的断点指令。但这并代表真的没有。因为没有这样的基本功能,顶层的调试功能怎么工作的啊。在AMD的工具链中,无论是CodeXL还是ROCm-GDB都是支持断点功能的。

那么是哪条指令呢?我觉得是S_TRAP。这是可以在GPU程序中触发陷阱的指令,与x86的INT n指令如出一辙。

GCN定义了十几种指令编码格式,S_TRAP属于SOPP类型,其编码格式如下图所示。

可见,S_TRAP指令的长度是一个DWORD(32位),低16位为立即数,用来指示陷阱号(TRAP_ID)。因为高位部分是固定的,所以S_TRAP指令的机器码总是0xBF92xxxx这样的编码。

迷信一点说,我第一次看到S_TRAP指令就觉得亲切,觉得它可以用来实现断点功能。但是调试器中是否真的使用这个指令设置断点,还是另有妙方呢?

这个周末在写作《软件调试》中的相关内容。虽然凭经验和直觉,觉得上面的推测把握很大。但是没有官方文档描述,也没有源代码证实,把推测的结论写进书里让我很不安。

怎么办呢?无奈之时,突然灵光一现。可以上IDA啊。IDA是著名的反汇编工具。引起名称与著名的程序员之母Ada Lovelace相似,所以其图标是就是Ada。

几年前曾经购买过正版的IDA,但是光盘和注册码不知在何处了。只好临时到官网下载一个免费版本。

安装很顺利,启动IDA,美丽的图标一闪,就到主界面了。打开AMD官方调试SDK中的核心调试模块(DBE)。然后找到用来设置软件断点的API——HwDbgCreateCodeBreakpoint。

HwDbgCreateCodeBreakpoint内部经过几次调用,最终执行实际断点设置和恢复的是下面这个方法:

bool HwDbgBreakpoint::Set(HwDbgBreakpoint *const this, bool enable)

在这个函数内部,看到多处0xBFxxxxxx这样的“身影”:

cmp     eax, 0BF800000h

cmp     eax, 0BF920000h

上面一个是S_NOP指令的机器码,后一个就是S_TRAP。特别地,下面这几条指令让我如释重负:

.text: 002017A8                 mov     edx, 0BF920007h

.text: 002017AD                 mov     rax, [rdi]

.text: 002017B0                 call    qword ptr [rax+18h]

其中的0BF920007h是触发TRAP_ID为7的陷阱,结合另一处看到的常量定义:

var TRAP_ID_DEBUGGER         = 0x07

于是,可以确定无疑,官方调试SDK中设置代码断点的方法就是使用S_TRAP指令,更确切地说,是S_TRAP 0x7。这与INT 3何其相似。

感谢IDA,感谢Ada!

AI时代,我们一起学习GPU。希望深入学习GPU的格友,欢迎垂询第二期GPU研习班。

***********************************************************

正心诚意,格物致知,以人文情怀审视软件,以软件技术改变人生。

欢迎关注格友公众号

AMD GPU的断点指令相关推荐

  1. Ubuntu 安装 AMD GPU 驱动

    基于环境 Ubuntu18.04 AMD-RX580 显卡 AMD 官网下载驱动 https://www.amd.com/en/support 将驱动上传到 Ubuntu 系统并解压 $ cd ~/D ...

  2. AMD GPU驱动,ROCM,Pytorch安装教程(A卡6700xt)

    我用的操作系统为ubuntu20.04,其他系统应该类似,只是命令稍有不同. 安装AMD GPU驱动 AMD驱动下载地址:https://www.amd.com/en/support/kb/relea ...

  3. AMD GPU内存管理(1):概览

    参考内核版本:Linux-6.1.8 HMM 待更新...... dumb buffer create/map 在AMDGPU的Graphics业务中,用到了GEM(Graphics Executio ...

  4. 【Stable Diffusion/NovelAI Diffusion的AMD GPU加速推理探索】

    测试机子配置: 1:AMD RX6600(显存8g)+i5 12600KF 16g内存 (台式机) 2:RTX 3070 laptop(显存8g)+i7 10870H 32g内存 (HP暗夜精灵笔记本 ...

  5. AMD GPU任务调度(3) —— fence机制

    文章目录 GPU fence command format EOP event DMA fence 数据结构 dma-fence amdgpu-fence dma_fence_ops amdgpu_f ...

  6. rocm平台_TensorFlow通过AMD GPU加速(ROCm/Ubuntu 18.04)

    ROCm 1.91之后不需要安装AMD GPU驱动程序.请参考新的安装流程: 通过AMD开发ROCm平台,TensorFlow可以使用AMD GPU实现GPU加速.现将搭建流程呈上. 硬件: CPU: ...

  7. 开源gpu_Linux游戏销售,AMD GPU开源驱动程序以及更多开源游戏新闻

    开源gpu 您好,开放游戏迷! 在本周的版本中,我们来看看两个游戏销售,AMD GPU开源驱动程序,新的开源游戏硬件等等! 2015年11月21日至27日开放游戏摘要 野性互动和Steam销售 Fer ...

  8. 三星发布Exynos 2200,AMD GPU加持,支持144Hz刷新率

    1.铠侠全球首发EDSFF PCIe 5.0 SSD:延迟骤降60% 铠侠发布了CD7系列SSD,全球第款采用企业和数据中心专用EDSFF E3.S形态的PCIe 5.0 SSD,BiCS TLC原厂 ...

  9. python调用gpu amd_python-将Keras和Tensorflow与AMD GPU一起使用

    这篇文章的原始问题是:如何使Keras和Tensorflow与AMD GPU一起运行. 这个问题的答案如下: 1.)如果您可以使Tensorflow正常工作(可选地在您的虚拟/ conda环境中),则 ...

最新文章

  1. 技术走向管理一些思考(1)-性格特质和自我管理
  2. 【转】不分英文字母大小寫的字串比較方式
  3. 数据库部分重点内容回顾
  4. 聚焦2020云栖大会 边缘计算专场畅谈技术应用创新
  5. Windows 2000服务器安全配置精华技巧
  6. 用java画网状图_如何在背景中绘制一个带网格线的漂亮条形图?
  7. linux top 参数详解
  8. indesign用于产品排班_2019年机器人行业十大新品盘点,过去一年最受关注的产品都在这...
  9. 《火车头采集器采集网页数据》fiddler2抓包工具使用图文教程。
  10. 使用PYTHON采集船舶MMSI数据
  11. 力扣刷题 DAY_61 回溯
  12. 彩色模型,及RGB,CMY,CMYK,HSI,CIE,YIQ,YUV相互转化及介绍
  13. Deferred Shading介绍
  14. gcc ------ 编译与链接选项及CFLAGS、LDFLAGS、LIBS
  15. 计算机专业英语教程(第二版)Chapter 4 Database Fundamentals
  16. ale插件 vim_Vim中异步语法检查ale配置
  17. 八、Pytorch学习之十九种损失函数
  18. 沈阳二本计算机工资,想进国家电网?这两所二本超过很多985!
  19. 微信小程序集成实时音视频通话功能
  20. 一句话完美去除plt保存图像的白边 (plt.savefig去白边, 坐标值和轴)

热门文章

  1. Going Home - ( 抽屉原理 )
  2. 解读,产业链和价值链的联系和区别
  3. 日冕物质抛射检测matlab,中国科学技术大学 日冕物质抛射研究取得重要进展
  4. 数字图像处理学习笔记-图像处理基础1
  5. Mac OS Catalina (10.15)下编译Redis Desktop Manager(RDM)
  6. RedisDesktopManager死活连接不上,网上的各种方法都失败了,可能于网络策略配置有关!!!
  7. Pascal's Triangle帕斯卡三角形算法
  8. SQL的INSERT INTO的几种写法
  9. microbit python_刘鹏涛老师用Microbit 学Python系列教程
  10. Java学习基础(二)