欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > [CUDA] ptx使用笔记

[CUDA] ptx使用笔记

2024/11/5 5:40:28 来源:https://blog.csdn.net/mingshili/article/details/143492459  浏览:    关键词:[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));

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com