从0-1学习CUDA | week 1

Week 1

  • 复习 C/C++ (pointers, memory, functions).
  • 安装 NVIDIA CUDA Toolkit + drivers.
  • 运行一个CUDA例子 (deviceQuery, vectorAdd).

学习目标

  • 巩固:回顾 CUDA 编程所必需的 C/C++ 核心概念。
  • 安装:成功安装 NVIDIA CUDA 工具包和兼容的显卡驱动。
  • 验证:编译并运行官方 CUDA 示例,确保环境配置正确。
  • 理解:掌握最基本的 CUDA 编程模型和核心概念。

第 1 步:巩固 C/C++ 核心知识 (Pointers, Memory, Functions)

CUDA C++ 是 C++ 的一个扩展。在深入学习 CUDA 之前,必须对以下几个 C/C++ 概念有扎实的理解,因为您将频繁地手动管理主机(CPU)和设备(GPU)之间的内存。

1.1 指针 (Pointers)

指针是一个存储内存地址的变量。在 CUDA 中,您会用到指向 CPU 内存的指针(主机指针)和指向 GPU 内存的指针(设备指针)。

核心概念回顾:

  • 声明 : int* ptr; 声明一个指向整数的指针。
  • 取地址 (&) : int var = 10; ptr = &var; ptr 现在存储着 var 的内存地址。
  • 解引用 (*) : *ptr = 20; 通过指针修改了 var 的值,现在 var 变成了 20。

C++

c 复制代码
// C++ Pointer Refresher
#include <iostream>

void main() {
    int value = 10;
    int* pointerToValue = &value; // 指针存储了 value 的地址

    std::cout << "Original value: " << value << std::endl;
    std::cout << "Address of value (&value): " << &value << std::endl;
    std::cout << "Pointer holds address: " << pointerToValue << std::endl;

    // 使用指针修改值
    *pointerToValue = 50;

    std::cout << "New value after dereferencing: " << value << std::endl;
}

1.2 内存管理 (Stack vs. Heap)

  • 栈 (Stack) : 用于存储局部变量和函数调用信息。内存由编译器自动管理,函数返回时自动释放。速度快,但空间有限。
  • 堆 (Heap) : 用于动态分配内存,大小和生命周期由程序员手动控制。空间大,但需要显式地申请和释放,否则会导致内存泄漏。

在 CUDA 中,cudaMalloc() 类似于 C 语言的 malloc(),它在 GPU 的全局内存(一种堆内存) 中分配空间。

核心概念回顾:

  • C 语言方式 (malloc/free) :

    C

    c 复制代码
    int* arr = (int*) malloc(10 * sizeof(int)); // 在堆上分配10个整数的空间
    // ... 使用 arr ...
    free(arr); // 必须手动释放
  • C++ 方式 (new/delete) :

    C++

    arduino 复制代码
    int* arr = new int[10]; // 在堆上分配10个整数的空间
    // ... 使用 arr ...
    delete[] arr; // 必须手动释放数组

1.3 函数与函数指针

函数是执行特定任务的代码块。在 CUDA 中,您将编写在 GPU 上执行的特殊函数,称为"核函数 (Kernel)"。理解普通 C++ 函数的传值和传引用对于理解如何将数据传递给核函数至关重要。

核心概念回顾:

  • 传值 (Pass-by-Value) : 函数接收的是实参的副本。
  • 传指针 (Pass-by-Pointer) : 函数接收的是实参的地址,可以修改原始数据。
  • 传引用 (Pass-by-Reference, C++) : 类似于传指针,但语法更简洁。

C++

c 复制代码
// C++ Function Refresher
#include <iostream>

void modifyValue(int* ptr) {
    *ptr = 100; // 通过指针修改原始数据
}

int main() {
    int myVar = 5;
    std::cout << "Original myVar: " << myVar << std::endl;

    modifyValue(&myVar); // 传递 myVar 的地址

    std::cout << "Modified myVar: " << myVar << std::endl; // 输出 100
    return 0;
}

第 2 步:安装 NVIDIA CUDA Toolkit 和驱动

这是最关键的一步。驱动程序让操作系统能够与 NVIDIA GPU 通信,而 CUDA Toolkit 提供了编译器(NVCC)、库和 API,让您能够编写 GPU 程序。

2.1 检查硬件

首先,确保您的计算机上有一个 NVIDIA 的 CUDA-Capable GPU。

  • Windows: 打开"设备管理器" > "显示适配器",查看是否有 NVIDIA GeForce, RTX, Quadro, Tesla, 等型号。
  • Linux : 在终端中运行 lspci | grep -i nvidia

2.2 下载 CUDA Toolkit

  1. 访问官方网站:NVIDIA CUDA Toolkit Download
  2. 根据您的操作系统(Windows, Linux, macOS)、架构 (x86_64)、发行版和版本进行选择。
  3. 建议选择 network (网络) 安装程序,它会下载最新的组件。

2.3 安装步骤

  • Windows:

    1. 运行下载的 .exe 文件。
    2. 选择"Express (推荐)"安装选项。这会同时安装 CUDA 工具包和最新的兼容驱动程序
    3. 按照向导完成安装。安装程序会自动设置系统环境变量(如 CUDA_PATH)。
  • Linux (以 Ubuntu 为例) :

    1. 官网会提供一系列终端命令。严格按照顺序 复制并执行它们。这通常包括添加 NVIDIA 的软件源、更新包列表以及安装 cuda 包。

    2. 安装命令示例:

      Bash

      arduino 复制代码
      wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
      sudo dpkg -i cuda-keyring_1.1-1_all.deb
      sudo apt-get update
      sudo apt-get -y install cuda-toolkit-12-5
    3. 安装完成后,根据提示将 CUDA 路径添加到您的 ~/.bashrc 文件中:

      Bash

      bash 复制代码
      echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
      echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
      source ~/.bashrc

2.4 验证安装

安装完成后,打开一个新的终端(或命令提示符)并运行以下命令:

  1. 验证驱动程序:

    Bash

    复制代码
    nvidia-smi

    如果此命令成功运行并显示您的 GPU 信息和驱动版本,说明驱动已正确安装。

  2. 验证 CUDA 编译器 (NVCC) :

    Bash

    css 复制代码
    nvcc --version

    此命令应显示您安装的 NVCC 编译器版本。

如果这两个命令都成功执行,您的 CUDA 环境已准备就绪!


第 3 步:运行 CUDA 示例

CUDA Toolkit 自带了许多示例代码,是验证环境和学习的最佳起点。

3.1 找到示例代码

  • Windows : C:\ProgramData\NVIDIA Corporation\CUDA Samples\v<version>
  • Linux : ~/NVIDIA_CUDA-<version>_Samples/usr/local/cuda/samples

将示例目录复制到一个您有写入权限的位置,例如您的用户主目录。

Bash

bash 复制代码
# Linux
cuda-install-samples-12.5.sh ~/
cd ~/NVIDIA_CUDA-12.5_Samples/

3.2 编译并运行 deviceQuery

deviceQuery 会枚举系统中的所有 CUDA 设备并显示其属性。

  1. 进入 deviceQuery 目录:

    Bash

    bash 复制代码
    cd 1_Utilities/deviceQuery
  2. 编译:

    • Linux : 运行 make
    • Windows : 打开该目录下的 Visual Studio .sln 文件并生成项目。
  3. 运行:

    Bash

    bash 复制代码
    ./deviceQuery

    您应该会看到类似下面的输出,列出了您的 GPU 名称、计算能力、内存大小等。最重要的是最后一行:

    erlang 复制代码
    ...
    Device 0: "NVIDIA GeForce RTX 4080"
      CUDA Driver Version / Runtime Version          12.5 / 12.5
      ...
    Result = PASS

3.3 编译并运行 vectorAdd

vectorAdd 是一个经典的并行计算入门程序,它在 GPU 上执行两个向量的相加。

  1. 返回示例根目录,进入 vectorAdd 目录:

    Bash

    bash 复制代码
    cd ../../0_Simple/vectorAdd
  2. 编译 (同上,make 或 Visual Studio)。1

  3. 运行:2

    Bash

    bash 复制代码
    ./vectorAdd

    如果一切正常,您会看到:3

    css 复制代码
    [Vector addition of 50000 elements]
    Copy input data from the host memory to the CUDA device
    CUDA kernel launch with 196 blocks of 256 threads
    Copy output data from the CUDA device to the host memory
    Test PASSED
    Done

看到 Result = PASSTest PASSED 意味着您的 CUDA 环境和硬件工作完全正常!


第 4 步:阅读《CUDA by Example》第 1-2 章

现在您的环境已经就绪,是时候理解背后的理论了。请阅读《CUDA by Example: An Introduction to General-Purpose GPU Programming》的前两章。

关键概念总结 (Chapters 1-2)

  • CPU (Host) vs. GPU (Device) : CUDA 编程涉及主机和设备两端。代码在主机上启动,但计算密集型部分(称为核函数)被发送到设备上执行。

  • 核函数 (Kernel) : 使用 __global__ 修饰符声明的函数。当主机调用核函数时,它会在 GPU 上由成百上千个线程并行执行。

  • 基本 CUDA 流程:

    1. 分配内存 : 在主机 (malloc/new) 和设备 (cudaMalloc()) 上都分配内存。
    2. 传输数据 : 使用 cudaMemcpy() 将输入数据从主机内存复制到设备内存。
    3. 执行核函数 : 主机调用核函数 kernel_name<<<...>>>() 在设备上执行计算。
    4. 传回数据 : 使用 cudaMemcpy() 将计算结果从设备内存复制回主机内存。
    5. 释放内存 : 释放主机 (free/delete) 和设备 (cudaFree()) 上的内存。
  • 线程层次结构 : CUDA 使用 Grid -> Block -> Thread 的层次结构来组织线程。您在调用核函数时指定要启动多少个线程块 (Block) 以及每个块包含多少个线程 (Thread)。

完成以上所有步骤后,您将拥有一个正常工作的 CUDA 开发环境,并对并行计算的基本模型有了初步的了解,为后续更深入的学习奠定了坚实的基础。祝您学习顺利!

相关推荐
格林威10 分钟前
工业相机如何通过光度立体成像技术实现高效精准的2.5D缺陷检测
人工智能·深度学习·数码相机·yolo·计算机视觉
MarkHD15 分钟前
大语言模型入门指南:从原理到实践应用
人工智能·语言模型·自然语言处理
A尘埃16 分钟前
NLP(自然语言处理, Natural Language Processing)
人工智能·自然语言处理·nlp
dlraba80216 分钟前
机器学习实战(二):Pandas 特征工程与模型协同进阶
人工智能·机器学习·pandas
一碗白开水一19 分钟前
【第19话:定位建图】SLAM点云配准之3D-3D ICP(Iterative Closest Point)方法详解
人工智能·算法
mit6.82420 分钟前
[rStar] 策略与奖励大语言模型
人工智能·语言模型
CV-杨帆27 分钟前
论文阅读:arxiv 2023 Large Language Models are Not Stable Recommender Systems
论文阅读·人工智能·语言模型
羊羊小栈35 分钟前
基于「YOLO目标检测 + 多模态AI分析」的植物病害检测分析系统(vue+flask+数据集+模型训练)
人工智能·yolo·目标检测·毕业设计·创业创新·大作业
胡耀超1 小时前
5、Python-NumPy科学计算基础
开发语言·人工智能·python·深度学习·numpy
茜茜西西CeCe1 小时前
数字图像处理-图像的基本运算
图像处理·人工智能·计算机视觉·matlab·图像的基本运算