[CUDA] ptx使用笔记

文章目录

  • 官方网站
  • 常用指令
    • 1. 基本写法
    • 2. 一些基本指令用法
  • 如何编译出ptx代码
  • 为什么用ptx代码

官方网站

PTX ISA doc: 包括PTX的一些指令集的使用手册。
PTX compiler API: The PTX Compiler APIs are a set of APIs which can be used to compile a PTX program into GPU assembly code. 一个可能被使用的场景是在分离的ptx与主程序应用中,通过更新ptx模块代码,让主程序使用最新的ptx特性。(而不是将ptx嵌入到主程序中,然后每次都有编译所有的程序。)
PTX Writer’s Guide to Interoperability互操作性: This document defines the Application Binary Interface (ABI) for the CUDA® architecture when generating PTX. By following the ABI, external developers can generate compliant PTX code that can be linked with other code.
Inline PTX Assembly in CUDA: The reference guide for inlining PTX (parallel thread execution) assembly statements into CUDA. 也就是怎么在cuda中写PTX代码。

常用指令

1. 基本写法

PTX:

  • 源模块是ASCII文本。行由换行字符(\n)分隔。
  • PTX是区分大小写的,并使用小写字母作为关键字。
  • PTX源模块具有汇编语言风格的语法,包括指令操作码和操作数。伪操作用于指定符号和地址管理。
  • 每个PTX模块必须以.version指令开始,指定PTX语言版本,然后是.target指令,指定假定的目标架构。
  • 指令关键字以点开头,因此不可能会与用户定义的标识符发生冲突
// 声明一个寄存器变量addr, 类型是u64.
.reg .u64 addr; 

2. 一些基本指令用法

  • 包括: .pred, setp, @p, ld.global.v4.u32 ... 以及cuda中如何嵌入asm代码

参考实例来源:https://github.com/mit-han-lab/torchsparse/blob/master/torchsparse/backend/utils/memory.cuh

template <int bytes>
struct global_load;template <>
struct global_load<16> {__device__ __inline__ global_load(uint4& D, void const* ptr, int pred_guard) {uint4& data = *reinterpret_cast<uint4*>(&D);// 应该也可以使用 __asm__ __volatile__.// 下面这段ptx指令表示为,但是更加有效:// if (static_cast<int>(pred_guard & (1 << ldg_idx)) != 0) {//  data = *(ptr_ldg + ldg_idx);// },。asm volatile("{\n"// 下面一段话代表声明一个谓词变量, 谓词变量的应该可以等同于表达式或者一个行为变量。"  .reg .pred p;\n"// .pred的变量经常是和setp一起使用的,这ptx的意思是将p = (int)(pred_guard & 1) != 0// setp:  Comparison and Selection Instructions: Compare two numeric values with a relational operator, and (optionally) combine this result with a predicate value by applying a Boolean operator.// ne 表示不等于not equal.// %5 表示ascii后面的第五个参数,从0开始计数; 所以是(int)(pred_guard & 1)的值"  setp.ne.b32 p, %5, 0;\n"// 注意下面这四行命令,表示将data.x = data.x, 因为D声明为 uint4 D = make_uint4(0,0,0,0);// 所以这四行命令其实是延迟执行这个初始化,也就是将D.x, D.y,D.z,D.w 初始化为0;"  mov.b32 %0, %6;\n""  mov.b32 %1, %7;\n""  mov.b32 %2, %8;\n""  mov.b32 %3, %9;\n"// @p 表示if(p==true) / if(p)的意思; 如果p=true, 则执行ld.global.v4// 注意v4表示vector为4 elems。 写法固定,用大括号括起来目的地址,用中括号括起来源地址。"  @p ld.global.v4.u32 {%0, %1, %2, %3}, [%4];\n""}\n"// =r 中有等号,表示目的地址; 而后面没有等号且用“:”分开的是原地址; 注意目的地址和原地址要用":"分开。: "=r"(data.x), "=r"(data.y), "=r"(data.z), "=r"(data.w): "l"(ptr), "r"((int)(pred_guard & 1)), "r"(data.x), "r"(data.y),"r"(data.z), "r"(data.w));}
};

如何编译出ptx代码

# 编译出ptx指令
nvcc -arch=sm_80 -ptx test.cu -o test.ptx
# 查看二进制文件中的汇编
nvcc -arch=sm_80 test.cu -o a.out
# 但是这个查看后的汇编和ptx不太一致,需要对比着看
objdump/cuobjdump -d a.out > log.txt

为什么用ptx代码

  • 还是按照上面的例子来说,ptx代码比C++代码产生的ptx代码命令更少
// 首先,如上面例子中所示,两行if语句通过 nvcc编译成ptx后,的代码如下所示:
// C++:
if (static_cast<int>(pred_guard & 1) != 0) {*in_data = *reinterpret_cast<uint4*>(ptr);}// generated ptx: 12行指令
and.b32          %r17, %r16, 1;
setp.eq.b32         %p1, %r17, 1;
mov.pred         %p2, 0;
xor.pred          %p3, %p1, %p2;
not.pred         %p4, %p3;
mov.u32         %r30, 0;
mov.u32         %r31, %r30;
mov.u32         %r32, %r30;
mov.u32         %r33, %r30;
@%p4 bra         $L__BB2_2;cvta.to.global.u64         %rd3, %rd1;
ld.global.v4.u32         {%r33, %r32, %r31, %r30}, [%rd3];// 用户自定义的ptx,就少好一些复杂的指令
// 7行指令
asm volatile("{\n""  .reg .pred p;\n""  setp.ne.b32 p, %5, 0;\n""  mov.b32 %0, %6;\n""  mov.b32 %1, %7;\n""  mov.b32 %2, %8;\n""  mov.b32 %3, %9;\n""  @p ld.global.v4.u32 {%0, %1, %2, %3}, [%4];\n""}\n": "=r"(in_data->x), "=r"(in_data->y), "=r"(in_data->z),"=r"(in_data->w) : "l"(ptr), "r"(static_cast<int>(pred_guard & 1)),"r"(in_data->x),"r"(in_data->y), "r"(in_data->z), "r"(in_data->w));

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kafka里的consumer 是推还是拉?

大家好&#xff0c;我是锋哥。今天分享关于【kafka里的consumer 是推还是拉&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; kafka里的consumer 是推还是拉&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Kafka中&#xff0c;消费者&…

Visual Studio | 配置管理

文章目录 一、配置管理1、项目属性1.1、常规1.2、VC 目录1.3、C/C -> 常规1.4、C/C -> 预处理器1.5、C/C -> 预编译头1.6、连接器 -> 常规1.7、连接器 -> 输入 2、编辑2.1、显示空格或tab符 一、配置管理 1、项目属性 1.1、常规 字段功能目标平台版本用于生成…

Docker打包自己项目推到Docker hub仓库(windows10)

一、启用Hyper-V和容器特性 1.应用和功能 2.点击程序和功能 3.启用或关闭Windows功能 4.开启Hyper-V 和 容器特性 记得重启生效&#xff01;&#xff01;&#xff01; 二、安装WSL2&#xff1a;写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/143057041 三…

js.轮转数组和旋转链表

这是两个相似的题型&#xff0c;一个是数组&#xff0c;另一个是链表。 链接&#xff1a;189. 轮转数组 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1:…

mysql left join group_concat 主表丢失数据

问题出现的场景&#xff1a; 有一个主表 a&#xff0c;一个子表 b a表有两条数据&#xff0c;a表第一条数据在b表中有一条子数据&#xff0c;a表第二条数据在b表中有两条子数据。 现在想要查询出来a表的所有数据和a表的子表b的id&#xff0c;b的id 使用GROUP_CONCAT拼接 有…

Spring 中循环依赖 三级缓存

在Spring框架中&#xff0c;循环依赖是一个常见的问题&#xff0c;它指的是两个或多个Bean之间互相依赖&#xff0c;形成一个闭环&#xff0c;导致无法准确地完成对象的创建和初始化。为了解决这个问题&#xff0c;Spring引入了三级缓存机制。以下是对Spring中循环依赖和三级缓…

新能源汽车与公共充电桩布局

近年来,全球范围内对新能源汽车产业的推动力度不断增强,中国新能源汽车市场也呈现蓬勃发展的势头,在政策与市场的共同推动下,新能源汽车销量持续增长。然而,据中国充电联盟数据显示,充电基础设施建设滞后于新能源汽车数量增长的现状导致充电桩供需不平衡,公共充电桩服务空白区域…

【深度学习基础】常用图像卷积核类型

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 常…

一二三应用开发平台自定义查询设计与实现系列3——通用化重构

通用化重构 前面我们以一个实体为目标对象&#xff0c;完成了功能开发与调试。 在此基础上&#xff0c;我们对功能进行重构&#xff0c;使其成为平台的标准化、通用化的功能。 前端重构 首先&#xff0c;先把自定义组件挪到了平台公共组件目录下&#xff0c;如下&#xff1…

RabbitMQ交换机类型

RabbitMQ交换机类型 1、RabbitMQ工作模型2、RabbitMQ交换机类型2.1、Fanout Exchange&#xff08;扇形&#xff09;2.1.1、介绍2.1.2、示例2.1.2.1、生产者2.1.2.2、消费者2.1.2.3、测试 2.2、Direct Exchange&#xff08;直连&#xff09;2.2.1、介绍2.2.2、示例2.2.2.1、生产…

qt QMenuBar详解

1、概述 QMenuBar是Qt框架中用于创建菜单栏的类&#xff0c;它继承自QWidget。QMenuBar通常位于QMainWindow对象的标题栏下方&#xff0c;用于组织和管理多个QMenu&#xff08;菜单&#xff09;和QAction&#xff08;动作&#xff09;。菜单栏提供了一个水平排列的容器&#x…

数据转换 | Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法

目录 基本介绍程序设计参考资料获取方式 基本介绍 Matlab基于SP符号递归图&#xff08;Symbolic recurrence plots&#xff09;一维数据转二维图像方法 符号递归图(Symbolic recurrence plots)是一种一维时间序列转图像的技术&#xff0c;可用于平稳和非平稳数据集;对噪声具有…

特殊矩阵的压缩存储

一维数组的存储结构 ElemType arr[10]; 各数组元素大小相同&#xff0c;且物理上连续存放。 数组元素a[i]的存放地址 LOC i * sizeof(ElemType)。&#xff08;LOC为起始地址&#xff09; 二维数组的存储结构 ElemType b[2][4];二维数组也具有随机存取的特性&#xff08;需…

MySQL utf8mb3 和 utf8mb4引发的问题

问题描述 Cause: java.sql.SQLException: Incorrect string value: \xF4\x8F\xBB\xBF-b... for column sddd_aaa_ark at row 1 sddd_aaa_ark 存储中文字符时&#xff0c;出现上述问题 原因分析 sddd_aaa_ark在数据库中结构是 utf8字符的最大字节数是3 byte&#xff0c;但是某些…

RK3568开发板Openwrt文件系统构建

RK3568开发板Openwrt文件系统构建 iTOP-RK3568开发板使用教程更新&#xff0c;后续资料会不断更新&#xff0c;不断完善&#xff0c;帮助用户快速入门&#xff0c;大大提升研发速度。 本次更新内容为《iTOP-3568开发板文件系统构建手册》&#xff0c;对Openwrt文件系统的编译…

Linux之crontab使用

一&#xff0c;查看cron是否已经在运行 查看crontab的运行状态 sudo service cron statussystemctl status cron 开启crontab: sudo service cron startsudo service cron restart 二&#xff0c;编辑cron定时任务 crontab -e加入你自己的命令&#xff0c;定时跑脚本&a…

OpenEuler 使用ffmpeg x11grab捕获屏幕流,rtsp推流,并用vlc播放

环境准备 安装x11grab(用于捕获屏幕流)和libx264(用于编码) # 基础开发环境&x11grab sudo dnf install -y \autoconf \automake \bzip2 \bzip2-devel \cmake \freetype-devel \gcc \gcc-c \git \libtool \make \mercurial \pkgconfig \zlib-devel \libX11-devel \libXext…

矩阵的奇异值分解SVD

为了论述矩阵的奇异值与奇异值分解!需要下面的结论!

H5开发指南|掌握核心技术,玩转私域营销利器

随着互联网技术的不断发展和用户需求的日益增长&#xff0c;H5页面逐渐成为了企业和个人展示信息、吸引用户关注的重要手段。具有跨平台兼容性强、网页链接分享、更新迭代方便快捷、低开发成本、可搜索和优化、数据分析与追踪、灵活性与扩展性以及无需下载安装等特点。不仅可以…

Ubuntu Linux

背景 Ubuntu起源于南非&#xff0c;其名称“Ubuntu”来源于非洲南部祖鲁语或豪萨语&#xff0c;意为“人性”、“我的存在是因为大家的存在”&#xff0c;这体现了非洲传统的一种价值观。Ubuntu由南非计算机科学家马克沙特尔沃斯&#xff08;Mark Shuttleworth&#xff09;创办…