CUDA 调试器 sanitizer,检测数据竞争,竞争条件 race condition

有数据竞争的代码 race.cu

cpp 复制代码
#include <cuda_runtime.h>
#include <stdio.h>
#include <stdlib.h>

// 有明显数据竞争的内核
__global__ void raceConditionKernel(int *data, int N) {
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    
    // 数据竞争:多个线程同时写入 data[0]
    if (tid < N) {
        data[0] += data[tid];  // 所有线程都竞争写入 data[0]
    }
}

// 共享内存数据竞争
__global__ void sharedMemoryRaceKernel(int *output) {
    __shared__ int shared_var;
    
    // 数据竞争:多个线程同时初始化
    if (threadIdx.x < 10) {
        shared_var = threadIdx.x;  // 多个线程竞争写入
    }
    
    __syncthreads();
    
    if (threadIdx.x == 0) {
        *output = shared_var;
    }
}

// 更复杂的数据竞争
__global__ void complexRaceKernel(int *data, int N) {
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    __shared__ int temp[256];
    
    temp[threadIdx.x] = tid;
    __syncthreads();
    
    // 数据竞争:多个线程写入 data[tid % 10]
    if (tid < N) {
        int target_index = tid % 10;  // 只有10个不同的索引
        data[target_index] += temp[threadIdx.x % 256];
    }
}

int main() {
    const int N = 1000;
    int *d_data, *h_data;
    
    // 分配内存
    cudaMalloc(&d_data, N * sizeof(int));
    h_data = (int*)malloc(N * sizeof(int));
    
    // 初始化数据
    for (int i = 0; i < N; i++) {
        h_data[i] = i + 1;
    }
    
    cudaMemcpy(d_data, h_data, N * sizeof(int), cudaMemcpyHostToDevice);
    
    printf("Running kernels with race conditions...\n");
    
    // 运行有数据竞争的内核
    dim3 blocks(10);
    dim3 threads(100);
    
    // 内核1:全局内存竞争
    printf("1. Global memory race condition:\n");
    raceConditionKernel<<<blocks, threads>>>(d_data, N);
    cudaDeviceSynchronize();
    
    // 内核2:共享内存竞争
    printf("2. Shared memory race condition:\n");
    int *d_output;
    cudaMalloc(&d_output, sizeof(int));
    sharedMemoryRaceKernel<<<1, 32>>>(d_output);
    cudaDeviceSynchronize();
    
    // 内核3:复杂竞争
    printf("3. Complex race condition:\n");
    complexRaceKernel<<<blocks, threads>>>(d_data, N);
    cudaDeviceSynchronize();
    
    // 读取结果
    cudaMemcpy(h_data, d_data, N * sizeof(int), cudaMemcpyDeviceToHost);
    
    printf("First 10 results: ");
    for (int i = 0; i < 10; i++) {
        printf("%d ", h_data[i]);
    }
    printf("\n");
    
    // 清理
    cudaFree(d_data);
    cudaFree(d_output);
    free(h_data);
    
    printf("Program completed.\n");
    return 0;
}

命令:

bash 复制代码
nvcc -g -G race.cu
compute-sanitizer --tool racecheck ./a.out

试了几次,只能检测到第二种数据竞争,不知道为什么

相关推荐
FreakStudio3 天前
亲测可用!可本地部署的 MicroPython 开源仿真器
python·单片机·嵌入式·面向对象·并行计算·电子diy·电子计算机
FreakStudio5 天前
和做工厂系统的印尼老哥,复刻了一套属于 MicroPython 的包管理系统
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
FreakStudio8 天前
做了个Claude Code CLI 电子宠物:程序员的实体监工代码搭子
python·单片机·嵌入式·面向对象·并行计算·电子diy·电子计算机
FreakStudio11 天前
无硬件学LVGL—定时器篇:基于Web模拟器+MicroPython速通GUI开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
FreakStudio13 天前
无硬件学LVGL:基于Web模拟器+MiroPython速通GUI开发—布局与空间管理篇
python·单片机·嵌入式·面向对象·并行计算·电子diy
FreakStudio19 天前
嘉立创开源:应该是全网MicroPython教程最多的开发板
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy
FreakStudio1 个月前
ESP32居然能当 DNS 服务器用?内含NCSI欺骗和DNS劫持实现
python·单片机·嵌入式·面向对象·并行计算·电子diy
神工坊1 个月前
技术分享︱多重参考系模型在风扇通风仿真中的自动化实现:精度与效率的工程平衡
算法·hpc·并行计算·cfd·cae·流体力学·风扇仿真
Icys2 个月前
Vulkan Cooperative Matrix 简明教程
并行计算·vulkan
小烤箱4 个月前
CUDA 编程完全理解系列(第四篇):硬件视角下的索引变量与分级内存机制
cuda·并行计算·感知算法