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 在进行大量重复运算的性能优势。

相关推荐
a未来永远是个未知数6 分钟前
构建机部署之git安装(Linux)
linux·git·elasticsearch
疯狂的rabbit.10 分钟前
Linux防火墙
linux·运维·服务器·云计算·redhat·rhce·openeular
YCyjs27 分钟前
云计算【第一阶段(26)】Linux网络设置
linux·运维·服务器·网络·云计算
真果粒wrdms1 小时前
【在线词典】项目实现
linux·c语言·嵌入式硬件·算法·udp·sqlite3
顧棟1 小时前
【Hive实战】Linux磁盘空间不足导致HiveSession创建失败
linux·hive·hadoop
henan程序媛1 小时前
LVS+Keepalived群集
linux·服务器·lvs·keepalived·双机热备份
故事讲予风听2 小时前
iptables与firewalld
linux·服务器·网络·网络安全
掘根2 小时前
【Linux】touch
java·linux·服务器
不死鸟.亚历山大.狼崽子2 小时前
python库(6):Pygments库
linux·开发语言·python
夜流冰3 小时前
GNU/Linux - Kconfig Language - 2
linux