• CUDA


    CUDA 简介

    CUDA(Compute Unified Device Architecture,统一计算架构)是由 NVIDIA 开发的并行计算平台和编程模型。它允许开发人员利用 NVIDIA GPU 的并行计算能力来加速应用程序的执行。
    CUDA 使开发人员能够使用类似 C 语言的编程语言来写代码,并通过 CUDA 编译器将其编译成可以在 GPU 上运行的代码。

    CUDA的主要组成部分包括:

    • CUDA 编程模型:允许开发人员使用 C 语言或 C++ 来编写代码,并通过特定的扩展和语法来利用GPU的并行计算能力。
    • CUDA 运行时 API:提供了一系列的函数和接口,用于在主机 CPU 和 GPU 之间进行数据传输、管理设备内存、启动并行计算任务等。
    • CUDA 工具集:包括了编译器、调试器、性能分析器等工具,帮助开发人员进行 CUDA 程序的开发、调试和优化。
    • CUDA 库:包括了一系列针对特定计算任务优化的库函数,例如线性代数、图像处理等。

    通过 CUDA,开发人员可以利用 GPU 的大规模并行计算能力来加速各种类型的应用程序,包括科学计算、深度学习、图形渲染等领域的应用。

    示例

    add.cu

    #include 
    
    __global__ void add(int a, int b, int *c) {
        *c = a + b;
    }
    
    int main() {
        int c;
        int *d_c;
    
        // Allocate memory on the device
        cudaMalloc((void **)&d_c, sizeof(int));
    
        // Launch the kernel with one thread
        add<<<1, 1>>>(2, 7, d_c);
    
        // Copy the result back to the host
        cudaMemcpy(&c, d_c, sizeof(int), cudaMemcpyDeviceToHost);
    
        // Free device memory
        cudaFree(d_c);
    
        // Print the result
        printf("2 + 7 = %d\n", c);
    
        return 0;
    }
    
    nvidia@nvidia-desktop:~$ nvcc add.cu -o add.out
    nvidia@nvidia-desktop:~$ ./add.out 
    2 + 7 = 9
    

    性能对比

    实验环境:

    平台:NVIDIA Jetson AGX Orin Developer Kit - Jetpack 6.0
    内存:32GB(CPU 和 GPU 共享该物理内存)
    CPU:12 核 Cortex-A78,2.2GHz
    GPU:2048核,930MHz(最大频率 1.3GHz)
    AI 性能:275 TOPS

    vector_add_4.cu

    #include 
    #include 
    #include 
    #include 
    
    // CUDA kernel for vector addition
    __global__ void vector_add(const float* A, const float* B, float* C, int N) {
        int i = blockDim.x * blockIdx.x + threadIdx.x;
        if (i < N) {
            C[i] = A[i] + B[i];
        }
    }
    
    // CPU implementation of vector addition
    void vector_add_cpu(const float* A, const float* B, float* C, int N) {
        for (int i = 0; i < N; ++i) {
            C[i] = A[i] + B[i];
        }
    }
    
    // Function to measure elapsed time
    double get_elapsed_time(struct timespec* start, struct timespec* end) {
        double start_sec = start->tv_sec + start->tv_nsec / 1.0e9;
        double end_sec = end->tv_sec + end->tv_nsec / 1.0e9;
        return end_sec - start_sec;
    }
    
    int main() {
        int N = 100000000;
        size_t size = N * sizeof(float);
    
        // Allocate memory on host
        float *h_A = (float*)malloc(size);
        float *h_B = (float*)malloc(size);
        float *h_C = (float*)malloc(size);
        float *h_C_GPU = (float*)malloc(size);
    
        // Initialize vectors
        for (int i = 0; i < N; ++i) {
            h_A[i] = (float)i;
            h_B[i] = (float)(i * 2);
        }
    
        // Measure CPU execution time
        struct timespec start_cpu, end_cpu;
        clock_gettime(CLOCK_MONOTONIC, &start_cpu);
        vector_add_cpu(h_A, h_B, h_C, N);
        clock_gettime(CLOCK_MONOTONIC, &end_cpu);
        double duration_cpu = get_elapsed_time(&start_cpu, &end_cpu);
        printf("CPU time: %f ms\n", duration_cpu * 1000);
    
        // Allocate memory on device
        float *d_A, *d_B, *d_C;
        cudaMalloc(&d_A, size);
        cudaMalloc(&d_B, size);
        cudaMalloc(&d_C, size);
    
        // Copy vectors from host to device
        cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
        cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
    
        // Measure GPU execution time
        int threads_per_block = 256;
        int blocks_per_grid = (N + threads_per_block - 1) / threads_per_block;
    
        struct timespec start_gpu, end_gpu;
        clock_gettime(CLOCK_MONOTONIC, &start_gpu);
        vector_add<<<blocks_per_grid, threads_per_block>>>(d_A, d_B, d_C, N);
        cudaDeviceSynchronize(); // Ensure the kernel has finished
        clock_gettime(CLOCK_MONOTONIC, &end_gpu);
        double duration_gpu = get_elapsed_time(&start_gpu, &end_gpu);
        printf("GPU time: %f ms\n", duration_gpu * 1000);
    
        // Copy result from device to host
        cudaMemcpy(h_C_GPU, d_C, size, cudaMemcpyDeviceToHost);
    
        // Verify the result
        int match = 1;
        for (int i = 0; i < N; ++i) {
            if (h_C[i] != h_C_GPU[i]) {
                match = 0;
                break;
            }
        }
        if (match) {
            printf("Results match!\n");
        } else {
            printf("Results don't match!\n");
        }
    
        // Clean up
        free(h_A);
        free(h_B);
        free(h_C);
        free(h_C_GPU);
        cudaFree(d_A);
        cudaFree(d_B);
        cudaFree(d_C);
    
        return 0;
    }
    
    
    
    nvidia@nvidia-desktop:~/cuda$ nvcc vector_add_4.cu -o vector_add_4.out
    nvidia@nvidia-desktop:~/cuda$ ./vector_add_4.out 
    CPU time: 353.779487 ms
    GPU time: 9.406352 ms
    Results match!
    nvidia@nvidia-desktop:~/cuda$ ./vector_add_4.out 
    CPU time: 354.594090 ms
    GPU time: 9.629491 ms
    Results match!
    nvidia@nvidia-desktop:~/cuda$ ./vector_add_4.out 
    CPU time: 354.699086 ms
    GPU time: 9.630452 ms
    Results match!
    nvidia@nvidia-desktop:~/cuda$ ./vector_add_4.out 
    CPU time: 353.854822 ms
    GPU time: 9.317967 ms
    Results match!
    nvidia@nvidia-desktop:~/cuda$ ./vector_add_4.out 
    CPU time: 353.836809 ms
    GPU time: 9.618131 ms
    Results match!
    nvidia@nvidia-desktop:~/cuda$ ./vector_add_4.out 
    CPU time: 354.636534 ms
    GPU time: 9.556850 ms
    Results match!
    
    

    执行 1 亿次加法运算,CPU 耗时 350ms 左右,GPU 耗时 9ms 左右,可以看到 GPU 在进行大量重复运算的性能优势。

  • 相关阅读:
    第一章 操作系统概述
    git 常用命令
    Termius 8.4.0(多协议远程管理软件)
    Objective-C blocks 概要
    Idea Mac版本 打不开、点击没反应、报错
    基于未知环境碰撞冲突预测的群机器人多目标搜索研究
    SHELL中if的使用
    Flutter开发- iOS 问题CocoaPods not installed or not in valid state
    Fruit-Dataset水果数据集+水果分类识别训练代码(支持googlenet, resnet, inception_v3, mobilenet_v2)
    Arthas之类操作
  • 原文地址:https://blog.csdn.net/lyndon_li/article/details/139222903