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

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

相关推荐
小烤箱16 天前
CUDA 编程完全理解系列(第四篇):硬件视角下的索引变量与分级内存机制
cuda·并行计算·感知算法
小烤箱18 天前
CUDA 编程完全理解系列(第二篇):从 Block 生命周期理解调度
自动驾驶·cuda·并行计算·感知算法
小烤箱19 天前
CUDA 编程完全理解系列(第一篇):GPU 的设计哲学与硬件架构基础
自动驾驶·硬件架构·cuda·并行计算·感知算法
2401_841495641 个月前
并行程序设计与实现
c++·python·算法·cuda·mpi·并行计算·openmp
charlie1145141911 个月前
AVX 指令集系列深度介绍:领域、意义、以及 AVX AVX2 的基本用法与样例
开发语言·c++·人工智能·软件工程·并行计算·avx
shimly1234564 个月前
(done) 并行计算 CS149 Lecture10 (DNN评估与优化)
人工智能·神经网络·dnn·并行计算
FreakStudio5 个月前
一文速通 Python 并行计算:教程总结
python·pycharm·嵌入式·面向对象·并行计算
FreakStudio7 个月前
一文速通 Python 并行计算:13 Python 异步编程-基本概念与事件循环和回调机制
python·pycharm·协程·多进程·并行计算·异步编程
FreakStudio8 个月前
一文速通 Python 并行计算:12 Python 多进程编程-进程池 Pool
python·嵌入式·面向对象·多进程·并行计算·电子diy