统计一条cuda ld指令需要经过哪些硬件单元--演示CuAssembler如何修改CUDA SASS指令

embedded/2024/9/18 5:42:19/ 标签: CUDA, GPU, 人工智能, 性能优化, 性能分析, SASS

统计一条cuda ld指令需要经过哪些硬件单元--演示CuAssembler如何修改CUDA SASS指令

  • 1.准备SASS反汇编工具CuAssembler
  • 2.仅包含ld.global.cv.f32的cuda kernel,如果不加st指令,编译器会将ld指令也优化掉。后面手动修改汇编指令删除掉st指令
  • 3.生成fatbin
  • 4.修改SASS指令,删除掉STG.E.STRONG.SYS指令,重新生成fatbin
  • 5.准备测试程序,加载fatbin并运行里面的Kernel
  • 6.ncu profing
  • 7.获取NCU支持的metrics列表
  • 8.查询每个metrics
  • 9.过滤掉值为0的metrics

背景:想统计一条ld指令需要经过哪些硬件单元
步骤:

  • cuda Kernel里只包含一条load指令,但如果没有st会被编译器优化掉(ptx还在,但sass里却没了)
  • 暂时没有找到编译选项关掉该优化
  • 于是采用CuAssembler将ST SASS指令删掉,重新生成fatbin
  • 采用cuModuleLoad加载fatbin,用cuLaunchKernel运行该Kernel

SASSCuAssembler_10">1.准备SASS反汇编工具CuAssembler

git clone https://github.com/cloudcores/CuAssembler
export PATH=${PATH}:$PWD/CuAssembler/bin:/usr/local/cuda/bin/
export PYTHONPATH=${PYTHOPATH}:$PWD/CuAssembler/
pip install pyelftools

2.仅包含ld.global.cv.f32的cuda kernel,如果不加st指令,编译器会将ld指令也优化掉。后面手动修改汇编指令删除掉st指令

tee ptx_ld_inst.cu<<-'EOF'
#include <iostream>
#include <cuda_runtime.h>
__global__ void ptx_ld_inst_kernel(float *input, float *out) {float d;int tid  = threadIdx.x + blockIdx.x * blockDim.x;asm("ld.global.cv.f32 %0, [%1];" : "=f"(d) : "l"(&input[tid]));asm("st.global.wt.f32 [%0],%1;" :: "l"(&out[tid]),"f"(d));
}
EOF

3.生成fatbin

# 生成ptx
/usr/local/cuda/bin/nvcc -std=c++17 -dc -lineinfo -arch=sm_86 -ptx ptx_ld_inst.cu -o ptx_ld_inst.ptx
# 生成cubin
/usr/local/cuda/bin/nvcc -arch=sm_86 ptx_ld_inst.ptx -cubin -o ptx_ld_inst.cubin
# 生成fatbin
/usr/local/cuda/bin/nvcc -arch=sm_86 ptx_ld_inst.cubin -fatbin -o ptx_ld_inst.fatbin
# 查看ptx
cat ptx_ld_inst.ptx
# 查看sass指令
/usr/local/cuda/bin/cuobjdump --dump-sass ptx_ld_inst.fatbin
# 输出:/*0070*/                   LDG.E.STRONG.SYS R3, [R2.64] ;         /* 0x0000000402037981 *//* 0x000ea2000c1f5900 *//*0080*/                   IMAD.WIDE R4, R4, R5, c[0x0][0x168] ;  /* 0x00005a0004047625 *//* 0x000fca00078e0205 *//*0090*/                   STG.E.STRONG.SYS [R4.64], R3 ;         /* 0x0000000304007986 *//* 0x004fe2000c115904 *//*00a0*/                   EXIT ;                                 /* 0x000000000000794d */

SASSSTGESTRONGSYSfatbin_54">4.修改SASS指令,删除掉STG.E.STRONG.SYS指令,重新生成fatbin

cuasm.py ptx_ld_inst.cubin ptx_ld_inst.cuasm
cat ptx_ld_inst.cuasm | grep "STG.E.STRONG.SYS"  -B 2
# 输出[B------:R-:W2:-:S01]         /*0070*/                   LDG.E.STRONG.SYS R3, desc[UR4][R2.64] ;[B------:R-:W-:Y:S05]         /*0080*/                   IMAD.WIDE R4, R4, R5, c[0x0][0x168] ;[B--2---:R-:W-:-:S01]         /*0090*/                   STG.E.STRONG.SYS desc[UR4][R4.64], R3 ;# 删除这二行
sed '/STG.E.STRONG.SYS/d' -i ptx_ld_inst.cuasm
sed '/IMAD.WIDE R4/d' -i ptx_ld_inst.cuasm# 生新行成cubin
cuasm.py ptx_ld_inst.cuasm
# 生成fatbin
/usr/local/cuda/bin/nvcc -arch=sm_86 ptx_ld_inst.cubin -fatbin -o ptx_ld_inst.fatbin
# 查看sass指令
/usr/local/cuda/bin/cuobjdump --dump-sass ptx_ld_inst.fatbin
输出:/*0050*/                   IMAD R4, R3, c[0x0][0x0], R4 ;           /* 0x0000000003047a24 *//* 0x001fc800078e0204 *//*0060*/                   IMAD.WIDE R2, R4, R5, c[0x0][0x160] ;    /* 0x0000580004027625 *//* 0x000fcc00078e0205 *//*0070*/                   LDG.E.STRONG.SYS R3, desc[UR4][R2.64] ;  /* 0x0000000402037981 *//* 0x000ea2200c1f5900 *//*0080*/                   EXIT ;                                   /* 0x000000000000794d */

5.准备测试程序,加载fatbin并运行里面的Kernel

tee ptx_ld_inst_main.cpp<<-'EOF'
#include <stdio.h>
#include <string.h>
#include <cuda_runtime.h>
#include <cuda.h>int main(int argc,char *argv[])
{CUresult error;CUdevice cuDevice;cuInit(0);int deviceCount = 0;error = cuDeviceGetCount(&deviceCount);error = cuDeviceGet(&cuDevice, 0);if(error!=CUDA_SUCCESS){printf("Error happened in get device!\n");}CUcontext cuContext;error = cuCtxCreate(&cuContext, 0, cuDevice);if(error!=CUDA_SUCCESS){printf("Error happened in create context!\n");}CUmodule module;CUfunction function;const char* module_file = "ptx_ld_inst.fatbin";const char* kernel_name = "_Z18ptx_ld_inst_kernelPfS_";error = cuModuleLoad(&module, module_file);if(error!=CUDA_SUCCESS){printf("Error happened in load moudle %d!\n",error);}error = cuModuleGetFunction(&function, module, kernel_name);if(error!=CUDA_SUCCESS){printf("get function error!\n");}int data_size=sizeof(float)*8192;float *output_ptr=nullptr;float *input_ptr=nullptr;int cudaStatus=0;cudaStatus = cudaMalloc((void**)&input_ptr, data_size);cudaStatus = cudaMalloc((void**)&output_ptr, data_size);void *kernelParams[]= {(void*)&output_ptr, (void*)&input_ptr};cuLaunchKernel(function,1, 1, 1,32, 1, 1,0,0,kernelParams, 0);cudaFree(output_ptr);cudaFree(input_ptr);cuModuleUnload(module);cuCtxDestroy(cuContext);return 0;
}
EOF
g++ ptx_ld_inst_main.cpp -o ptx_ld_inst_main -I /usr/local/cuda/include -L /usr/local/cuda/lib64 -lcudart -lcuda

6.ncu profing

/usr/local/NVIDIA-Nsight-Compute/ncu --set full --section SpeedOfLight_HierarchicalTensorRooflineChart \--target-processes all --clock-control=none \--print-details all --export ncu_report_ptx_ld_inst -f ./ptx_ld_inst_main/usr/local/NVIDIA-Nsight-Compute/ncu --metrics \
l1tex__average_t_sectors_per_request_pipe_lsu_mem_global_op_ld.max_rate,\
l1tex__average_t_sectors_per_request_pipe_lsu_mem_global_op_ld.pct,\
l1tex__average_t_sectors_per_request_pipe_lsu_mem_global_op_ld.ratio,\
l1tex__data_bank_conflicts_pipe_lsu_mem_global_op_ld.max,\
l1tex__m_xbar2l1tex_read_bytes_mem_lg_op_ld.max,\
l1tex__m_xbar2l1tex_read_sectors_mem_lg_op_ld.max,\
l1tex__t_bytes_pipe_lsu_mem_global_op_ld.max,\
l1tex__t_bytes_pipe_lsu_mem_global_op_ld_lookup_miss.max,\
l1tex__t_output_wavefronts_pipe_lsu_mem_global_op_ld.max,\
l1tex__t_requests_pipe_lsu_mem_global_op_ld.max,\
l1tex__t_sectors_pipe_lsu_mem_global_op_ld.max,\
l1tex__t_sectors_pipe_lsu_mem_global_op_ld_lookup_miss.max,\
l1tex__t_set_accesses_pipe_lsu_mem_global_op_ld.max,\
l1tex__t_set_conflicts_pipe_lsu_mem_global_op_ld.max,\
sm__sass_data_bytes_mem_global_op_ld.max,\
sm__sass_inst_executed_op_global_ld.max,\
sm__sass_inst_executed_op_ld.max,\
sm__sass_l1tex_t_sectors_pipe_lsu_mem_global_op_ld.max,\
smsp__inst_executed_op_global_ld.max,\
smsp__inst_executed_op_global_ld_pred_on_any.max,\
smsp__sass_average_data_bytes_per_sector_mem_global_op_ld.max_rate,\
smsp__sass_average_data_bytes_per_sector_mem_global_op_ld.pct,\
smsp__sass_average_data_bytes_per_sector_mem_global_op_ld.ratio,\
smsp__sass_data_bytes_mem_global_op_ld.max,\
smsp__sass_inst_executed_op_global_ld.max,\
smsp__sass_inst_executed_op_ld.max,\
smsp__sass_l1tex_t_sectors_pipe_lsu_mem_global_op_ld.max  ./ptx_ld_inst_main

输出

 ----------------------------------------------------------------------- ----------- ------------Metric Name                                                             Metric Unit Metric Value----------------------------------------------------------------------- ----------- ------------l1tex__average_t_sectors_per_request_pipe_lsu_mem_global_op_ld.max_rate    sector/1           32l1tex__average_t_sectors_per_request_pipe_lsu_mem_global_op_ld.pct                %        12.50l1tex__average_t_sectors_per_request_pipe_lsu_mem_global_op_ld.ratio       sector/1            4l1tex__data_bank_conflicts_pipe_lsu_mem_global_op_ld.max                                       0l1tex__m_xbar2l1tex_read_bytes_mem_lg_op_ld.max                                byte          128l1tex__m_xbar2l1tex_read_sectors_mem_lg_op_ld.max                            sector            4l1tex__t_bytes_pipe_lsu_mem_global_op_ld.max                                   byte          128l1tex__t_bytes_pipe_lsu_mem_global_op_ld_lookup_miss.max                       byte          128l1tex__t_output_wavefronts_pipe_lsu_mem_global_op_ld.max                                       1l1tex__t_requests_pipe_lsu_mem_global_op_ld.max                                                1l1tex__t_sectors_pipe_lsu_mem_global_op_ld.max                               sector            4l1tex__t_sectors_pipe_lsu_mem_global_op_ld_lookup_miss.max                   sector            4l1tex__t_set_accesses_pipe_lsu_mem_global_op_ld.max                                            1l1tex__t_set_conflicts_pipe_lsu_mem_global_op_ld.max                          cycle            0sm__sass_data_bytes_mem_global_op_ld.max                                       byte          128sm__sass_inst_executed_op_global_ld.max                                        inst            1sm__sass_inst_executed_op_ld.max                                               inst            1sm__sass_l1tex_t_sectors_pipe_lsu_mem_global_op_ld.max                       sector            4smsp__inst_executed_op_global_ld.max                                           inst            1smsp__inst_executed_op_global_ld_pred_on_any.max                               inst            1smsp__sass_average_data_bytes_per_sector_mem_global_op_ld.max_rate      byte/sector           32smsp__sass_average_data_bytes_per_sector_mem_global_op_ld.pct                     %          100smsp__sass_average_data_bytes_per_sector_mem_global_op_ld.ratio         byte/sector           32smsp__sass_data_bytes_mem_global_op_ld.max                                     byte          128smsp__sass_inst_executed_op_global_ld.max                                      inst            1smsp__sass_inst_executed_op_ld.max                                             inst            1smsp__sass_l1tex_t_sectors_pipe_lsu_mem_global_op_ld.max                     sector            4----------------------------------------------------------------------- ----------- ------------

7.获取NCU支持的metrics列表

/usr/local/NVIDIA-Nsight-Compute/ncu --query-metrics \--csv | awk -F, '{print $1}' | sed 's/"//g' | tail -n +2 > metrics.txt

8.查询每个metrics

tee get_metrics.sh<<-'EOF'
rm -f ptx_ld_inst_metrics.txt
for line in `cat metrics.txt`
do/usr/local/NVIDIA-Nsight-Compute/ncu --metrics $line \./ptx_ld_inst_main 2>&1 | grep "$line" | grep -v "n/a" | tee -a "ptx_ld_inst_metrics.txt"/usr/local/NVIDIA-Nsight-Compute/ncu --metrics $line \./ptx_ld_inst_main 2>&1 | grep "$line" | grep -v "n/a" | tee -a "ptx_ld_inst_metrics.txt"
done
EOF
bash get_metrics.sh

9.过滤掉值为0的metrics


http://www.ppmy.cn/embedded/94470.html

相关文章

苹果备忘录删了怎么恢复?收藏3个方法就够了

在日常使用中&#xff0c;苹果备忘录因其便捷性成为了记录重要事项的好帮手。然而&#xff0c;意外删除备忘录内容时有发生&#xff0c;给我们的工作和生活带来不便。那么&#xff0c;备忘录删了怎么恢复呢&#xff1f;为此&#xff0c;我们特别整理了3种高效可靠的恢复方法&am…

MoonBit 周报 Vol.53:新增高级循环语法、引入字符串插值、MoonBit AI 支持代码解释!

weekly 2024-08-05 MoonBit更新 添加了基于 Iter 和 Iter2 类型的 for .. in 循环支持&#xff1a; fn main {for x in [ 1, 2, 3 ] {println(x)}for k, v in { "x": 1, "y": 2 } {println("\{k} > \{v}")} }for 与 in 之间可以使用 1&…

VBA 指定快捷键在Excel中粘贴指定缩放图片

1. 应用背景 做测试的时候需要在Excel文件中贴图&#xff0c;但是直接粘贴的话图片又太大&#xff0c;需要手动调整&#xff0c;这时就可以利用这个宏来实现一次性粘贴并调整好图片的大小。 2. 宏的制作 可以是.xlsm文件&#xff0c;将该文件放到[C:\Program Files\Microsof…

在Docker上部署Ollama+AnythingLLM完成本地LLM Agent部署

在当今快速发展的人工智能领域&#xff0c;本地部署大型语言模型&#xff08;LLM&#xff09;Agent正逐渐成为企业和研究者关注的焦点。本地部署不仅能够提供更高的数据安全性和隐私保护&#xff0c;还能减少对外部服务的依赖&#xff0c;提高响应速度和系统稳定性。本文将介绍…

阿里云智能大数据演进

本文根据7月24日飞天发布时刻产品发布会、7月5日DataFunCon2024北京站&#xff1a;大数据大模型.双核时代实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;徐晟 阿里云研究员/计算平台产品负责人 主要内容&#xff1a; Overview - 阿里云大数据 AI 产品…

六西格玛绿带培训对企业有什么帮助?

六西格玛&#xff0c;这一源自摩托罗拉、风靡全球的管理哲学和方法论&#xff0c;以其严谨的数据分析、持续改进的流程优化理念&#xff0c;帮助无数企业实现了从“好”到“卓越”的跨越。而六西格玛绿带&#xff0c;作为这一体系中的中坚力量&#xff0c;是连接高层管理者与一…

FPGA面试问题整理

1. 逻辑设计中竞争与冒险概念&#xff0c;如何识别和消除&#xff1f; 竞争&#xff1a;在组合逻辑电路中&#xff0c;信号经过多条路径到达输出端&#xff0c;每条路径经过的逻辑门不同存在时差&#xff0c;在信号变化的瞬间存在先后顺序。这种现象叫竞争。 冒险&#xff1a;由…

基于区块链的合同存证应用开发

基于区块链的合同存证应用开发 任务一:环境准备 1.启动区块链网络 目录: /root/xuperchain/output/ 启动区块链网络 bash constrol.sh start2.创建钱包账户 目录: /root/xuperchain/output/ 创建tenant, landlord钱包账户,命令如下: bin/xchain-cli account newke…

opencv-python实战项目二:图像模糊检测

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、简介&#xff1a;二、模糊图片检测方案三、算法实现步骤四、代码实现五、算法效果 一、简介&#xff1a; 在日常生活中&#xff0c;摄影已成为记录关键时刻的重…

leetcode 70. 爬楼梯

力扣 70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。&#xff08;1 < n < 45&#xff09; 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 方法1: class Solution { public:int climbStairs(int n) {int s 0;if(n 1) ret…

【机器学习sklearn实战】岭回归、Lasso回归和弹性网络

一 sklean中模型详解 1.1 Ride regression 1.2 Lasso regression 1.3 ElasticNet 二 算法实战 2.1 导入包 import numpy as np import pandas as pd from sklearn import datasets from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.linear…

开启仓颉编程

环境搭建 这里不重复&#xff0c;直接推荐文章 环境搭建 注意&#xff1a;是输入“Create Cangjie Project”&#xff0c;快捷键打开不会有提示。 目前只有vscode可以开发。 因为我接触的开发语语言c,c,java,c#,go&#xff0c;所以后期博文会主要提示不同的地方。

opencv-python图像增强一:传统图像去噪方法整理

一、简介&#xff1a; 在数字图像处理领域&#xff0c;噪声一直是影响图像质量的重要因素。无论是拍摄过程中的环境干扰&#xff0c;还是传输过程中的信号失真&#xff0c;噪声都可能导致图像模糊、细节丢失&#xff0c;甚至影响后续的图像分析和应用。为了提高图像的视觉效果…

【C++】值传递

函数值传递的特点&#xff1a;值传递过程中即使形参改变也不会改变实参 没有返回值的函数用“ void ”定义 下面是一个实例&#xff1a; #include<iostream> using namespace std;//值传递 //定义函数&#xff0c;实现两个数字进行交换函数//如果函数不需要返回值&…

新形势下职业教育物联网人才培养策略

一、引言 随着信息技术的快速发展&#xff0c;物联网技术作为新一代信息技术的重要组成部分&#xff0c;已经渗透到社会的各个领域。然而&#xff0c;当前职业教育在物联网人才培养方面仍面临诸多挑战&#xff0c;如教学目标不明确、教学内容与市场需求脱节等问题。因此&#…

邀请函 I 松下信息和望繁信科技邀您参加「数智时代下大数据应用的“道”与“术”」闭门会议

在数字化浪潮席卷全球的今天&#xff0c;大数据与智能化的结合成为企业成功的关键。为了深入探讨这一重要议题&#xff0c;松下信息系统&#xff08;上海&#xff09;有限公司&#xff08;简称“松下信息”&#xff09;与上海望繁信科技有限公司&#xff08;简称“望繁信科技”…

Linux编程---文件操作

标准 IO ANSI C 设计的一组用文件IO 封装的操作库函数 &#xff08;1&#xff09;IO&#xff1a; input output I&#xff1a; 键盘是标准输入设备 》默认输入就是指键盘 /dev/inputO&#xff1a; 显示器是标准输出设备 》默认输出就是指显示器 &#xff08;2&#xff0…

【AI人工智能】文心智能体 - 你的专属车牌设计师

引言 自AI盛行以来&#xff0c;不断有各种各样的人工智能产品崭露头角。我们逐步跟着不断产生的人工智能来使自己的工作和生活变得更加智能化&#xff01;那么我们是否能够创造一款专属于自己的人工智能产品呢&#xff1f; 文心智能体平台就给我们提供了这样的机会&#xff0c…

STM32点亮一盏灯

STM32是一种基于ARM Cortex-M系列微控制器的芯片&#xff0c;常用于嵌入式系统开发。要在STM32上点亮一盏LED灯&#xff0c;你需要按照以下步骤操作&#xff1a; 硬件连接&#xff1a; 将LED的一端连接到STM32的GPIO输出引脚&#xff0c;另一端通常接地或接VCC&#xff08;电源…

智能家居中高性能联网通信方案,乐鑫ESP32-S3/C3无线Wi-Fi蓝牙应用

随着科技的飞速发展&#xff0c;智能家居已经不再是科幻小说中的概念&#xff0c;而是走进了千家万户的现实生活。 智能家居是广泛的系统性产品概念&#xff0c;以住宅为载体&#xff0c;运用物联网、网络通信和人工智能等技术&#xff0c;接收信号并判断&#xff0c;提供更加…