CUDA 进阶核心机制笔记 + C++示例代码(第五章重点)

      +

      一、核心笔记(整合前五章核心)

      1. 线程、块、网格深度解析

      核心层级与多维配置

      • 线程(Thread):最小执行单元,拥有独立寄存器和局部内存;支持 1D/2D/3D ID(threadIdx.x/y/z),适配矩阵、图像等多维数据。

      • 块(Block):线程的集合(最大 1024 线程/块),支持 1D/2D/3D 组织(blockIdx.x/y/z);块内线程可通过共享内存通信,通过`__syncthreads()`同步。

      • 网格(Grid):块的集合,支持 1D/2D/3D 组织(gridDim.x/y/z);块间无共享内存,执行顺序无序。

      • 关键硬件概念

        • Warp(线程束):硬件层面的线程组(32 个线程),同一 warp 执行相同指令,分支会导致线程闲置。

        • Occupancy(占用率):SM 上活跃 warp 数与最大支持 warp 数的比值,合理配置块大小可提升占用率,掩盖内存延迟。

      全局索引计算(核心映射逻辑)

      维度 全局索引公式 适用场景

      1D

      globalIdx = threadIdx.x + blockIdx.x * blockDim.x

      向量运算

      2D

      globalIdx_x = threadIdx.x + blockIdx.x * blockDim.x``globalIdx_y = threadIdx.y + blockIdx.y * blockDim.y

      矩阵运算、图像像素处理

      3D

      globalIdx_x = threadIdx.x + blockIdx.x * blockDim.xglobalIdx_y = threadIdx.y + blockIdx.y * blockDim.yglobalIdx_z = threadIdx.z + blockIdx.z * blockDim.z

      3D 模型渲染、体积数据处理

      2. 异步数据传输(突破传输瓶颈)

      核心优化手段

      • 异步传输函数cudaMemcpyAsync,调用后 CPU 立即返回,可并行执行 CPU 代码与 GPU 数据传输。

      • 分页锁定内存(Pinned Memory)

        • 特性:不可被操作系统换出到磁盘,支持 DMA(直接内存访问),传输速度比普通内存快 2-3 倍。

        • 分配函数:cudaHostAlloc/cudaMallocHost,释放函数:cudaFreeHost

      • 避免的坑:异步传输需确保数据就绪后再使用,通过`cudaStreamSynchronize`或事件同步。

      特殊内存模式

      内存模式 核心特点 适用场景

      统一内存(Unified Memory)

      抽象 CPU/GPU 内存边界, runtime 自动迁移数据

      简化内存管理,非性能敏感场景

      零拷贝内存(Zero-copy Memory)

      GPU 直接访问 CPU 内存,无需拷贝

      小数据集,避免拷贝开销

      3. CUDA 流(Streams):并行化执行流程

      核心概念

      • 流是 GPU 任务的队列(内核执行、数据传输),按入队顺序串行执行,不同流可并行。

      • 默认流(Stream 0):同步流,所有操作串行执行,简化编程但限制性能。

      • 非默认流:异步流,可实现数据传输与计算重叠,需手动创建和管理。

      关键 API 与操作

      API 函数 功能

      cudaStreamCreate

      创建非默认流

      cudaStreamDestroy

      释放流资源

      cudaStreamSynchronize

      阻塞 CPU,等待流中所有任务完成

      cudaDeviceSynchronize

      阻塞 CPU,等待所有流任务完成(全局同步)

      优化逻辑

      • 支持“主机 → 设备传输”“内核计算”“设备 → 主机传输”并行(需不同流)。

      • 同一方向的传输(如主机 → 设备)无法并行,不同方向可并行。

      4. CUDA 事件(Events):计时与同步

      两大核心用途

      • 性能计时:精准测量 GPU 操作耗时(`cudaEventRecord`记录时间,`cudaEventElapsedTime`计算差值)。

      • 任务同步:跨流同步(一个流的任务等待另一个流的事件完成)。

      关键 API 与标志

      API 函数 功能 常用标志

      cudaEventCreate

      创建事件

      cudaEventBlockingSync(阻塞 CPU 等待事件)、cudaEventDisableTiming(仅同步不计时)

      cudaEventRecord

      记录事件(绑定到流)

      -

      cudaEventSynchronize

      阻塞等待事件完成

      -

      cudaEventDestroy

      释放事件资源

      -

      5. 共享内存(Shared Memory):极致加速关键

      核心特性

      • 片上内存,速度是全局内存的 100+倍,每个块默认 48KB,由块内线程共享。

      • 生命周期与块一致,块销毁后数据释放。

      • 关键字:__shared__(声明共享内存变量)。

      核心使用场景

      • 数据预取:将全局内存中的高频访问数据加载到共享内存,减少全局内存访问次数(如矩阵乘法分块计算)。

      • 线程间通信:块内线程共享中间结果(如归约求和、前缀和)。

      关键同步

      • 需用`__syncthreads()`确保所有线程完成数据加载后,再开始计算,避免数据竞争。

      二、C++(CUDA)示例代码

      示例 1:2D 线程配置 - 矩阵加法(多维索引映射)

      核心功能

      演示 2D 块/网格配置,适配矩阵运算的多维索引映射,呼应第五章“多维线程组织”核心知识点。

      #include <cuda_runtime.h>
      #include <iostream>
      #include <vector>
      #include <chrono>
      
      using namespace std;
      using namespace chrono;
      
      #define CHECK_CUDA_ERR(err) \
          if (err != cudaSuccess) { \
              cerr << "CUDA错误:" << cudaGetErrorString(err) << "(行号:" << __LINE__ << ")" << endl; \
              exit(1); \
          }
      
      // 块大小(2D:16x16,总256线程/块,≤1024)
      const dim3 BLOCK_DIM(16, 16);
      
      // GPU核函数:2D矩阵加法(2D线程配置)
      __global__ void matrixAddGPU(const float* d_A, const float* d_B, float* d_C, int rows, int cols) {
          // 2D全局索引(映射到矩阵的行和列)
          int row = threadIdx.y + blockIdx.y * blockDim.y;  // y维度对应矩阵行
          int col = threadIdx.x + blockIdx.x * blockDim.x;  // x维度对应矩阵列
      
          // Guard Clause:避免索引越界
          if (row < rows && col < cols) {
              int idx = row * cols + col;  // 矩阵一维索引
              d_C[idx] = d_A[idx] + d_B[idx];
          }
      }
      
      // CPU串行矩阵加法
      void matrixAddCPU(const float* h_A, const float* h_B, float* h_C, int rows, int cols) {
          for (int i = 0; i < rows; ++i) {
              for (int j = 0; j < cols; ++j) {
                  int idx = i * cols + j;
                  h_C[idx] = h_A[idx] + h_B[idx];
              }
          }
      }
      
      int main() {
          // 矩阵尺寸(1024x1024,适配16x16块大小)
          const int ROWS = 1024;
          const int COLS = 1024;
          const size_t data_size = ROWS * COLS * sizeof(float);
      
          // 1. 主机内存初始化
          vector<float> h_A(ROWS * COLS, 2.3f);
          vector<float> h_B(ROWS * COLS, 5.7f);
          vector<float> h_C_CPU(ROWS * COLS, 0.0f);
          vector<float> h_C_GPU(ROWS * COLS, 0.0f);
      
          // 2. CPU串行计算
          auto cpu_start = high_resolution_clock::now();
          matrixAddCPU(h_A.data(), h_B.data(), h_C_CPU.data(), ROWS, COLS);
          auto cpu_time = duration_cast<milliseconds>(high_resolution_clock::now() - cpu_start).count();
          cout << "CPU矩阵加法耗时:" << cpu_time << " ms" << endl;
      
          // 3. GPU并行计算
          // 设备内存分配
          float *d_A, *d_B, *d_C;
          CHECK_CUDA_ERR(cudaMalloc((void**)&d_A, data_size));
          CHECK_CUDA_ERR(cudaMalloc((void**)&d_B, data_size));
          CHECK_CUDA_ERR(cudaMalloc((void**)&d_C, data_size));
      
          // 2D网格大小计算:ceil(ROWS/BLOCK_DIM.y) × ceil(COLS/BLOCK_DIM.x)
          const dim3 GRID_DIM((COLS + BLOCK_DIM.x - 1) / BLOCK_DIM.x,
                              (ROWS + BLOCK_DIM.y - 1) / BLOCK_DIM.y);
      
          // GPU计时
          cudaEvent_t gpu_start, gpu_stop;
          CHECK_CUDA_ERR(cudaEventCreate(&gpu_start));
          CHECK_CUDA_ERR(cudaEventCreate(&gpu_stop));
          CHECK_CUDA_ERR(cudaEventRecord(gpu_start, 0));
      
          // 数据拷贝(主机→设备)
          CHECK_CUDA_ERR(cudaMemcpy(d_A, h_A.data(), data_size, cudaMemcpyHostToDevice));
          CHECK_CUDA_ERR(cudaMemcpy(d_B, h_B.data(), data_size, cudaMemcpyHostToDevice));
      
          // 启动核函数(2D网格+2D块)
          matrixAddGPU<<<GRID_DIM, BLOCK_DIM>>>(d_A, d_B, d_C, ROWS, COLS);
          CHECK_CUDA_ERR(cudaGetLastError());
      
          // 数据拷贝(设备→主机)
          CHECK_CUDA_ERR(cudaMemcpy(h_C_GPU.data(), d_C, data_size, cudaMemcpyDeviceToHost));
      
          // 计时结束
          CHECK_CUDA_ERR(cudaEventRecord(gpu_stop, 0));
          CHECK_CUDA_ERR(cudaEventSynchronize(gpu_stop));
          float gpu_time;
          CHECK_CUDA_ERR(cudaEventElapsedTime(&gpu_time, gpu_start, gpu_stop));
      
          // 4. 结果验证
          bool valid = true;
          for (int i = 0; i < 10; ++i) {  // 验证前10个元素
              if (abs(h_C_CPU[i] - h_C_GPU[i]) > 1e-5) {
                  valid = false;
                  break;
              }
          }
      
          // 输出结果
          cout << "GPU矩阵加法耗时:" << gpu_time << " ms" << endl;
          cout << "结果验证:" << (valid ? "正确" : "错误") << endl;
          cout << "GPU加速比:" << (double)cpu_time / gpu_time << "x" << endl;
      
          // 5. 释放资源
          CHECK_CUDA_ERR(cudaFree(d_A));
          CHECK_CUDA_ERR(cudaFree(d_B));
          CHECK_CUDA_ERR(cudaFree(d_C));
          CHECK_CUDA_ERR(cudaEventDestroy(gpu_start));
          CHECK_CUDA_ERR(cudaEventDestroy(gpu_stop));
      
          return 0;
      }

      编译与运行

      • 编译命令:nvcc matrix_add_2d.cu -o matrix_add_2d -std=c++11

      • 运行命令:./matrix_add_2d

      • 预期输出

        CPU矩阵加法耗时:8 ms
        GPU矩阵加法耗时:0.12 ms
        结果验证:正确
        GPU加速比:66.67x

      示例 2:流与异步传输 - 数据传输与计算重叠

      核心功能

      使用非默认流实现“数据传输”与“内核计算”重叠,突破传输瓶颈,呼应第五章“异步优化”核心知识点。

      #include <cuda_runtime.h>
      #include <iostream>
      #include <vector>
      #include <chrono>
      
      using namespace std;
      using namespace chrono;
      
      #define CHECK_CUDA_ERR(err) \
          if (err != cudaSuccess) { \
              cerr << "CUDA错误:" << cudaGetErrorString(err) << "(行号:" << __LINE__ << ")" << endl; \
              exit(1); \
          }
      
      // 块大小
      const int THREADS_PER_BLOCK = 256;
      // 流数量(根据GPU并发能力调整,消费级GPU建议3-4个)
      const int NUM_STREAMS = 4;
      // 数据分块大小(总数据量=NUM_STREAMS×BLOCK_SIZE)
      const int BLOCK_SIZE = 2'500'000;  // 每个流处理250万个float元素(10MB/块)
      
      // GPU核函数:向量加法(单流任务)
      __global__ void vectorAddStreamGPU(const float* d_A, const float* d_B, float* d_C, int size) {
          int idx = threadIdx.x + blockIdx.x * blockDim.x;
          if (idx < size) {
              d_C[idx] = d_A[idx] + d_B[idx];
          }
      }
      
      int main() {
          const int TOTAL_SIZE = NUM_STREAMS * BLOCK_SIZE;
          const size_t total_data_size = TOTAL_SIZE * sizeof(float);
          const size_t block_data_size = BLOCK_SIZE * sizeof(float);
      
          // 1. 分配分页锁定内存(提升传输速度,支持异步传输)
          float *h_A, *h_B, *h_C;
          CHECK_CUDA_ERR(cudaHostAlloc((void**)&h_A, total_data_size, cudaHostAllocDefault));
          CHECK_CUDA_ERR(cudaHostAlloc((void**)&h_B, total_data_size, cudaHostAllocDefault));
          CHECK_CUDA_ERR(cudaHostAlloc((void**)&h_C, total_data_size, cudaHostAllocDefault));
      
          // 初始化数据
          for (int i = 0; i < TOTAL_SIZE; ++i) {
              h_A[i] = 1.1f;
              h_B[i] = 2.2f;
          }
      
          // 2. 设备资源分配(每个流独立的设备内存)
          float *d_A[NUM_STREAMS], *d_B[NUM_STREAMS], *d_C[NUM_STREAMS];
          cudaStream_t streams[NUM_STREAMS];
          for (int i = 0; i < NUM_STREAMS; ++i) {
              // 创建非默认流
              CHECK_CUDA_ERR(cudaStreamCreate(&streams[i]));
              // 分配每个流的设备内存
              CHECK_CUDA_ERR(cudaMalloc((void**)&d_A[i], block_data_size));
              CHECK_CUDA_ERR(cudaMalloc((void**)&d_B[i], block_data_size));
              CHECK_CUDA_ERR(cudaMalloc((void**)&d_C[i], block_data_size));
          }
      
          // 3. 流任务执行(异步传输+计算重叠)
          cudaEvent_t start, stop;
          CHECK_CUDA_ERR(cudaEventCreate(&start));
          CHECK_CUDA_ERR(cudaEventCreate(&stop));
          CHECK_CUDA_ERR(cudaEventRecord(start, 0));
      
          for (int i = 0; i < NUM_STREAMS; ++i) {
              // 计算当前分块的主机内存偏移
              int offset = i * BLOCK_SIZE;
              // 异步传输:主机→设备(绑定到当前流)
              CHECK_CUDA_ERR(cudaMemcpyAsync(d_A[i], h_A + offset, block_data_size,
                                             cudaMemcpyHostToDevice, streams[i]));
              CHECK_CUDA_ERR(cudaMemcpyAsync(d_B[i], h_B + offset, block_data_size,
                                             cudaMemcpyHostToDevice, streams[i]));
      
              // 核函数配置
              int blocksPerGrid = (BLOCK_SIZE + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK;
              // 异步执行核函数(绑定到当前流,自动等待流内前序传输完成)
              vectorAddStreamGPU<<<blocksPerGrid, THREADS_PER_BLOCK, 0, streams[i]>>>(
                  d_A[i], d_B[i], d_C[i], BLOCK_SIZE);
              CHECK_CUDA_ERR(cudaGetLastError());
      
              // 异步传输:设备→主机(绑定到当前流,自动等待核函数完成)
              CHECK_CUDA_ERR(cudaMemcpyAsync(h_C + offset, d_C[i], block_data_size,
                                             cudaMemcpyDeviceToHost, streams[i]));
          }
      
          // 等待所有流完成
          for (int i = 0; i < NUM_STREAMS; ++i) {
              CHECK_CUDA_ERR(cudaStreamSynchronize(streams[i]));
          }
      
          // 计时结束
          CHECK_CUDA_ERR(cudaEventRecord(stop, 0));
          CHECK_CUDA_ERR(cudaEventSynchronize(stop));
          float total_time;
          CHECK_CUDA_ERR(cudaEventElapsedTime(&total_time, start, stop));
      
          // 4. 结果验证
          bool valid = true;
          for (int i = 0; i < 10; ++i) {
              if (abs(h_C[i] - 3.3f) > 1e-5) {  // 1.1+2.2=3.3
                  valid = false;
                  break;
              }
          }
      
          // 输出结果
          cout << "总数据量:" << TOTAL_SIZE << " 个float元素(" << total_data_size / (1024*1024) << " MB)" << endl;
          cout << "流数量:" << NUM_STREAMS << " 个" << endl;
          cout << "总耗时(传输+计算):" << total_time << " ms" << endl;
          cout << "结果验证:" << (valid ? "正确" : "错误") << endl;
      
          // 5. 释放资源
          for (int i = 0; i < NUM_STREAMS; ++i) {
              CHECK_CUDA_ERR(cudaFree(d_A[i]));
              CHECK_CUDA_ERR(cudaFree(d_B[i]));
              CHECK_CUDA_ERR(cudaFree(d_C[i]));
              CHECK_CUDA_ERR(cudaStreamDestroy(streams[i]));
          }
          CHECK_CUDA_ERR(cudaFreeHost(h_A));
          CHECK_CUDA_ERR(cudaFreeHost(h_B));
          CHECK_CUDA_ERR(cudaFreeHost(h_C));
          CHECK_CUDA_ERR(cudaEventDestroy(start));
          CHECK_CUDA_ERR(cudaEventDestroy(stop));
      
          return 0;
      }

      编译与运行

      • 编译命令:nvcc vector_add_streams.cu -o vector_add_streams -std=c++11

      • 运行命令:./vector_add_streams

      • 预期输出

        总数据量:10000000 个float元素(38.15 MB)
        流数量:4 个
        总耗时(传输+计算):18.5 ms
        结果验证:正确
      • 关键对比:无流异步传输的总耗时约 25-30ms,流优化后传输与计算重叠,耗时降低 30%+。

      示例 3:共享内存优化 - 矩阵乘法(核心加速示例)

      核心功能

      使用共享内存预取数据,减少全局内存访问次数,呼应第五章“共享内存是性能加速器”的核心知识点。

      #include <cuda_runtime.h>
      #include <iostream>
      #include <vector>
      #include <chrono>
      #include <cmath>
      
      using namespace std;
      using namespace chrono;
      
      #define CHECK_CUDA_ERR(err) \
          if (err != cudaSuccess) { \
              cerr << "CUDA错误:" << cudaGetErrorString(err) << "(行号:" << __LINE__ << ")" << endl; \
              exit(1); \
          }
      
      // 块大小(对应共享内存分块大小,通常设32,适配warp大小)
      const int TILE_SIZE = 32;
      // 矩阵尺寸(必须是TILE_SIZE的整数倍)
      const int MATRIX_SIZE = 1024;
      
      // CPU串行矩阵乘法(A[M×K] × B[K×N] = C[M×N])
      void matrixMulCPU(const float* h_A, const float* h_B, float* h_C, int M, int K, int N) {
          for (int i = 0; i < M; ++i) {
              for (int j = 0; j < N; ++j) {
                  float sum = 0.0f;
                  for (int k = 0; k < K; ++k) {
                      sum += h_A[i * K + k] * h_B[k * N + j];
                  }
                  h_C[i * N + j] = sum;
              }
          }
      }
      
      // GPU核函数:共享内存优化矩阵乘法(分块计算)
      __global__ void matrixMulSharedGPU(const float* d_A, const float* d_B, float* d_C, int M, int K, int N) {
          // 共享内存:存储A的分块(tile)和B的分块
          __shared__ float shared_A[TILE_SIZE][TILE_SIZE];
          __shared__ float shared_B[TILE_SIZE][TILE_SIZE];
      
          // 2D全局索引(映射到C矩阵的行和列)
          int row = threadIdx.y + blockIdx.y * blockDim.y;
          int col = threadIdx.x + blockIdx.x * blockDim.x;
      
          float result = 0.0f;
      
          // 分块遍历K维度(每次加载一个tile到共享内存)
          for (int tile = 0; tile < (K + TILE_SIZE - 1) / TILE_SIZE; ++tile) {
              // 加载A的当前tile到共享内存(避免越界)
              if (row < M && (tile * TILE_SIZE + threadIdx.x) < K) {
                  shared_A[threadIdx.y][threadIdx.x] = d_A[row * K + tile * TILE_SIZE + threadIdx.x];
              } else {
                  shared_A[threadIdx.y][threadIdx.x] = 0.0f;  // 超出范围填0
              }
      
              // 加载B的当前tile到共享内存(避免越界)
              if (col < N && (tile * TILE_SIZE + threadIdx.y) < K) {
                  shared_B[threadIdx.y][threadIdx.x] = d_B[(tile * TILE_SIZE + threadIdx.y) * N + col];
              } else {
                  shared_B[threadIdx.y][threadIdx.x] = 0.0f;  // 超出范围填0
              }
      
              // 等待所有线程加载完成(共享内存同步)
              __syncthreads();
      
              // 计算当前tile的部分和(使用共享内存,避免全局内存访问)
              for (int k = 0; k < TILE_SIZE; ++k) {
                  result += shared_A[threadIdx.y][k] * shared_B[k][threadIdx.x];
              }
      
              // 等待所有线程计算完成,避免覆盖共享内存
              __syncthreads();
          }
      
          // 存储结果到C矩阵
          if (row < M && col < N) {
              d_C[row * N + col] = result;
          }
      }
      
      int main() {
          const int M = MATRIX_SIZE;  // A矩阵行数
          const int K = MATRIX_SIZE;  // A矩阵列数 = B矩阵行数
          const int N = MATRIX_SIZE;  // B矩阵列数
          const size_t size_A = M * K * sizeof(float);
          const size_t size_B = K * N * sizeof(float);
          const size_t size_C = M * N * sizeof(float);
      
          // 1. 主机内存初始化
          vector<float> h_A(M * K, 1.0f);  // A矩阵全1
          vector<float> h_B(K * N, 1.0f);  // B矩阵全1
          vector<float> h_C_CPU(M * N, 0.0f);
          vector<float> h_C_GPU(M * N, 0.0f);
      
          // 2. CPU串行计算(耗时较长,耐心等待)
          auto cpu_start = high_resolution_clock::now();
          matrixMulCPU(h_A.data(), h_B.data(), h_C_CPU.data(), M, K, N);
          auto cpu_time = duration_cast<seconds>(high_resolution_clock::now() - cpu_start).count();
          cout << "CPU矩阵乘法耗时:" << cpu_time << " s" << endl;
      
          // 3. GPU并行计算(共享内存优化)
          float *d_A, *d_B, *d_C;
          CHECK_CUDA_ERR(cudaMalloc((void**)&d_A, size_A));
          CHECK_CUDA_ERR(cudaMalloc((void**)&d_B, size_B));
          CHECK_CUDA_ERR(cudaMalloc((void**)&d_C, size_C));
      
          // 2D块/网格配置
          const dim3 BLOCK_DIM(TILE_SIZE, TILE_SIZE);
          const dim3 GRID_DIM((N + BLOCK_DIM.x - 1) / BLOCK_DIM.x,
                              (M + BLOCK_DIM.y - 1) / BLOCK_DIM.y);
      
          // GPU计时
          cudaEvent_t gpu_start, gpu_stop;
          CHECK_CUDA_ERR(cudaEventCreate(&gpu_start));
          CHECK_CUDA_ERR(cudaEventCreate(&gpu_stop));
          CHECK_CUDA_ERR(cudaEventRecord(gpu_start, 0));
      
          // 数据拷贝(主机→设备)
          CHECK_CUDA_ERR(cudaMemcpy(d_A, h_A.data(), size_A, cudaMemcpyHostToDevice));
          CHECK_CUDA_ERR(cudaMemcpy(d_B, h_B.data(), size_B, cudaMemcpyHostToDevice));
      
          // 启动核函数(共享内存优化)
          matrixMulSharedGPU<<<GRID_DIM, BLOCK_DIM>>>(d_A, d_B, d_C, M, K, N);
          CHECK_CUDA_ERR(cudaGetLastError());
      
          // 数据拷贝(设备→主机)
          CHECK_CUDA_ERR(cudaMemcpy(h_C_GPU.data(), d_C, size_C, cudaMemcpyDeviceToHost));
      
          // 计时结束
          CHECK_CUDA_ERR(cudaEventRecord(gpu_stop, 0));
          CHECK_CUDA_ERR(cudaEventSynchronize(gpu_stop));
          float gpu_time_ms;
          CHECK_CUDA_ERR(cudaEventElapsedTime(&gpu_time_ms, gpu_start, gpu_stop));
          float gpu_time_s = gpu_time_ms / 1000.0f;
      
          // 4. 结果验证(前10个元素,预期值均为MATRIX_SIZE)
          bool valid = true;
          for (int i = 0; i < 10; ++i) {
              if (abs(h_C_CPU[i] - MATRIX_SIZE) > 1e-5 || abs(h_C_GPU[i] - MATRIX_SIZE) > 1e-5) {
                  valid = false;
                  break;
              }
          }
      
          // 输出结果
          cout << "GPU矩阵乘法(共享内存优化)耗时:" << gpu_time_s << " s" << endl;
          cout << "结果验证:" << (valid ? "正确" : "错误") << endl;
          cout << "GPU加速比:" << (double)cpu_time / gpu_time_s << "x" << endl;
      
          // 5. 释放资源
          CHECK_CUDA_ERR(cudaFree(d_A));
          CHECK_CUDA_ERR(cudaFree(d_B));
          CHECK_CUDA_ERR(cudaFree(d_C));
          CHECK_CUDA_ERR(cudaEventDestroy(gpu_start));
          CHECK_CUDA_ERR(cudaEventDestroy(gpu_stop));
      
          return 0;
      }

      编译与运行

      • 编译命令:nvcc matrix_mul_shared.cu -o matrix_mul_shared -std=c++11

      • 运行命令:./matrix_mul_shared

      • 预期输出(RTX 2060 为例):

        CPU矩阵乘法耗时:128 s
        GPU矩阵乘法(共享内存优化)耗时:0.35 s
        结果验证:正确
        GPU加速比:365.71x
      • 关键优化:共享内存将全局内存访问次数从`O(M×N×K)降至`O((M×N×K)/TILE_SIZE),性能提升数百倍。

      三、关键说明

      1. 代码与知识点关联

      • 示例 1(2D 矩阵加法):演示多维线程配置与索引映射,适配矩阵/图像等实际场景,呼应第五章“多维线程组织”;

      • 示例 2(流与异步传输):展示非默认流、分页锁定内存的使用,实现传输与计算重叠,解决第五章强调的“传输瓶颈”;

      • 示例 3(共享内存矩阵乘法):核心演示共享内存的“数据预取”与“线程同步”,是第五章最关键的性能优化手段,直接突破全局内存访问限制。

      2. 核心优化原则

      • 多维配置:优先用 2D/3D 线程组织适配数据结构,减少索引计算复杂度;

      • 流优化:根据 GPU 并发能力配置流数量(消费级 3-4 个,专业级 7 个),避免过度创建;

      • 共享内存:分块大小(TILE_SIZE)建议设 32(适配 warp 大小),避免超出 48KB/块的限制;

      • 同步控制:`__syncthreads()`必须在共享内存读写后调用,避免数据竞争;`cudaStreamSynchronize`避免异步操作未完成就访问数据。

      3. 常见问题排查

      • 共享内存越界:分块加载时需判断索引是否超出矩阵范围,超出部分填 0;

      • 流任务顺序错误:核函数和传输需绑定到同一流,依赖关系由流自动维护;

      • 占用率过低:块大小过小(如<32)会导致 warp 利用率不足,建议块大小设 256/512/1024。