测试cuda trap指令对warp的影响

测试cuda trap指令对warp的影响

本文测试cuda trap指令对warp的影响

1.测试方法

  • 分别测试smsp上不同的warp数,并且在指定上tid上执行__trap指令,看看对其它线程的影响

2.测试小结

  • 如果32*4个线程(每个smsp只有一个warp),所有的线程并行执行,tid==32+16执行__trap后Kernel就退出了,kernel out这一行不会打印
  • 如果是3244个线程(每个smsp有4个warp),他们轮流调度,所以在tid==32+16执行__trap之前 kernel out这一行打印有机会被调度,会打印出来
  • 所在,不管哪一个线程只要执行到__trap kernel就退出,没有执行到的线程正常运行,如果带着cuda-gdb,则会收到SIGTRAP
  • cuda kernel里执行到assert(0)或_brkpt()或__trap(),lanuch失败,之后的cudaMemcpy,cudaFree调用也会失败(也就得不到设备内存的数据)

3.测试步骤

c 复制代码
tee trap_inst_benchmark.cu<<-'EOF'
#include <iostream>
#include <cuda_runtime.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <cstdio>
#include <cuda.h>

#define CHECK_CUDA(call)                                           \
    do {                                                           \
        cudaError_t err = call;                                    \
        if (err != cudaSuccess) {                                  \
            std::cerr << "CUDA error at " << __FILE__ << ":" << __LINE__;  \
            std::cerr << " code=" << err << " (" << cudaGetErrorString(cudaGetLastError()) << ")" << std::endl; \
        }                                                          \
    } while (0)

__global__ void kernel(float *output_data,unsigned long long*output_ts,unsigned int*output_smid) {
    int tid  = threadIdx.x + blockIdx.x * blockDim.x;
    unsigned int smid;
    clock_t ts=clock64();
    asm volatile("mov.u32 %0, %smid;" : "=r"(smid));
    output_smid[tid]=smid;
    output_ts[tid]=ts;
    //output_data[tid]=tid;
    float val=tid;
    asm("st.global.wt.f32 [%0],%1;" :: "l"(&output_data[tid]),"f"(val));
    asm("discard.global.L2 [%0],128;" :: "l"(&output_data[tid]));
    asm("discard.global.L2 [%0],128;" :: "l"(&output_ts[tid]));
    
    printf("kernel in smid:%d tid:%02d val:%6.2f ts:%ld\n",smid,tid,output_data[tid],ts);

    if(tid==32+16)
    {      
        //__nanosleep(2378066193);
        printf("trap tid:%d smid:%d ts:%ld\n",tid,smid,ts);
        __trap();//assert(0);//__brkpt();//__trap();
        return;
    }  
    printf("kernel out smid:%d tid:%02d val:%6.2f ts:%ld\n",smid,tid,output_data[tid],ts);
}

int main(int argc,char *argv[])
{
    int deviceid=0;
    cudaSetDevice(deviceid);  
    int mode=atoi(argv[1]);
    
    int block_size=1;
    int thread_block_size=32*4*4;
    int thread_size=thread_block_size*block_size;

    int data_size=sizeof(float)*thread_size;
    int ts_size=sizeof(unsigned long long)*thread_size;
    int smid_size=sizeof(int)*thread_size;
    
    float *dev_output_data=nullptr;
    unsigned long long* dev_output_ts=nullptr;
    unsigned int* dev_smid=nullptr;

    float *host_output_data=new float[thread_size];
    unsigned long long*host_output_ts=new unsigned long long[thread_size];;
    unsigned int* host_smid=new unsigned int[thread_size];
        
    CHECK_CUDA(cudaMalloc((void**)&dev_output_data, data_size));
    CHECK_CUDA(cudaMalloc((void**)&dev_output_ts, ts_size));
    CHECK_CUDA(cudaMalloc((void**)&dev_smid, smid_size));
    
    CHECK_CUDA(cudaMemcpy(dev_output_data,host_output_data,data_size,cudaMemcpyHostToDevice));
    CHECK_CUDA(cudaMemcpy(dev_output_ts,host_output_ts,ts_size,cudaMemcpyHostToDevice));
    CHECK_CUDA(cudaMemcpy(dev_smid,host_smid,smid_size,cudaMemcpyHostToDevice));
    
    printf("dev_output_data:%p\n",dev_output_data);
    printf("dev_output_ts:%p\n",dev_output_ts);
    printf("dev_smid:%p\n",dev_smid);
    
    if(mode==0)
    {
        kernel<<<block_size, 32*4*4>>>(dev_output_data,dev_output_ts,dev_smid);
    }
    else
    {
        kernel<<<block_size, 32*4>>>(dev_output_data,dev_output_ts,dev_smid);
    }
    
    //如果Kernel里出现异常后,后面的CUDA API调用都会返回失败,自然也就得不到设备内存里的数据
    CHECK_CUDA(cudaDeviceSynchronize());
       
    CHECK_CUDA(cudaMemcpy(host_output_data,dev_output_data,data_size,cudaMemcpyDeviceToHost));
    CHECK_CUDA(cudaMemcpy(host_output_ts,dev_output_ts,ts_size,cudaMemcpyDeviceToHost));
    CHECK_CUDA(cudaMemcpy(host_smid,dev_smid,smid_size,cudaMemcpyDeviceToHost));
    
    for(int i=0;i<thread_size;i++)
    {
      //  printf("tid:%04d smid:%08d val:%6.2f ts:%lld\n",i,host_smid[i],host_output_data[i],host_output_ts[i]);
    }
    CHECK_CUDA(cudaFree(dev_output_data));
    CHECK_CUDA(cudaFree(dev_output_ts));
    return 0;
}
EOF

/usr/local/cuda/bin/nvcc -std=c++17 -arch=sm_86 -g -lineinfo -o trap_inst_benchmark trap_inst_benchmark.cu \
                -I /usr/local/cuda/include -L /usr/local/cuda/lib64 -lcuda
./trap_inst_benchmark 0 #能打印出kernel out
./trap_inst_benchmark 1 #不能打印出kernel out
相关推荐
fpcc15 小时前
并行编程实战——CUDA编程的图之六子图的创建
人工智能·cuda
明月醉窗台1 天前
[jetson] AGX Xavier 安装Ubuntu18.04及jetpack4.5
人工智能·算法·nvidia·cuda·jetson
桃酥4031 天前
GPU架构 - 零基础入门
ai·gpu
d1z8881 天前
(十八)32天GPU测试从入门到精通-TensorRT-LLM 部署与优化day16
人工智能·python·深度学习·gpu·tensorrt
飞翔的SA2 天前
全程 Python:无需离开 Python 即可实现光速级 CUDA 加速,无需c++支持
开发语言·c++·python·nvidia·cuda
CodeCraft Studio2 天前
LightningChart .NET v12.5.1 发布:高性能数据可视化再升级,赋能工业与实时数据场景
信息可视化·.net·gpu·数据可视化·lightningchart·高性能图表开发·数据可视化引擎
HyperAI超神经6 天前
【TVM教程】理解 Relax 抽象层
人工智能·深度学习·学习·机器学习·gpu·tvm·vllm
逻极6 天前
Windows平台Ollama AMD GPU编译全攻略:基于ROCm 6.2的实战指南(附构建脚本)
人工智能·windows·gpu·amd·ollama
阿钱真强道7 天前
01 飞腾 S5000C 服务器环境搭建实战:PyTorch + CUDA + RTX 4090D 安装与验证
pytorch·cuda·aarch64·深度学习环境搭建·飞腾服务器·s5000c·rtx4090d
酌量9 天前
nvidia orin agx刷机忘记CUDA runtime,安装torch和cuda
linux·笔记·ubuntu·torch·cuda·agx