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

c 复制代码
#include <stdio.h>

__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;
}
bash 复制代码
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

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

// 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;
}
bash 复制代码
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 在进行大量重复运算的性能优势。

相关推荐
Wy_编程2 分钟前
Linux-文本搜索工具grep
linux·运维·服务器
xujiangyan_5 分钟前
linux的sysctl系统以及systemd系统。
linux·服务器·网络
Lovyk8 分钟前
Linux Shell 常用操作与脚本示例详解
linux·运维·服务器
yuanpan4 小时前
ubuntu系统上的conda虚拟环境导出方便下次安装
linux·ubuntu·conda
AOwhisky5 小时前
Linux 文本处理三剑客:awk、grep、sed 完全指南
linux·运维·服务器·网络·云计算·运维开发
Gavin_9155 小时前
从零开始部署经典开源项目管理系统最新版redmine6-Linux Debian12
linux·ruby on rails·开源·debian·ruby·redmine
花小璇学linux6 小时前
imx6ull-驱动开发篇31——Linux异步通知
linux·驱动开发·嵌入式软件
shelutai6 小时前
ubuntu 编译ffmpeg6.1 增加drawtext,libx264,libx265等
linux·ubuntu·ffmpeg
runfarther6 小时前
搭建LLaMA-Factory环境
linux·运维·服务器·python·自然语言处理·ai编程·llama-factory
hello_ world.7 小时前
RHCA10NUMA
linux