CUDA多线程

devtools/2025/3/18 7:12:43/

一、基础

  1. 线程块与线程索引
    CUDA线程以‌线程块(Thread Block)‌为基本执行单元,每个线程块内包含多个线程,通过threadIdxblockIdx等内置变量定位线程位置。线程块在GPU上并行执行,同一块内的线程可通过共享内存高效通信‌。

  2. 块内同步:__syncthreads()
    用于同步线程块内所有线程的执行进度,确保共享内存的写入在所有线程可见后继续执行后续操作。例如,在累加共享内存时需两次同步:第一次清空内存,第二次汇总结果‌。

    __shared__ int sh_arr;
    if (threadIdx.x < 10) sh_arr[threadIdx.x] = 0;
    __syncthreads(); // 同步清空操作
    atomicAdd(&sh_arr[tid], 1);
    __syncthreads(); // 同步累加操作
  3. 全局同步限制
    CUDA默认不支持跨线程块的全局同步,需通过‌原子操作‌或‌协作组(Cooperative Groups)‌实现更复杂的同步逻辑。协作组允许自定义线程组粒度(如warp、网格级),并通过sync()方法同步‌。

二、‌核心机制 

  • 主上下文共享(运行时API)‌:
    • 同一进程的线程共享设备的主上下文(由cudaSetDevice隐式创建)。
    • 线程首次调用CUDA运行时API时自动附加到主上下文。
      #include <thread>
      #include <cuda_runtime.h>void thread_task(int device_id) {cudaSetDevice(device_id);  // 切换设备(主上下文自动附加)float *d_data;cudaMalloc(&d_data, 1024);  // 共享主上下文资源// ... 执行内核或内存操作
      }int main() {std::thread t1(thread_task, 0);  // 线程1使用设备0std::thread t2(thread_task, 1);  // 线程2使用设备1t1.join();t2.join();return 0;
      }
  • 线程局部上下文(驱动API)‌:
    • 使用cuCtxCreate + cuCtxPushCurrent显式创建独立上下文。
    • 每个线程维护独立的上下文堆栈。
      ‌1)独立上下文模式‌
      每个线程创建独立上下文,避免资源竞争,但需注意设备资源限制(如显存、流处理器占用)。
      // 线程函数
      void thread_func() {CUcontext ctx;cuCtxCreate(&ctx, 0, device);  // 每个线程独立创建上下文cuCtxPushCurrent(ctx);          // 设为当前上下文// 执行CUDA操作(如内存分配、内核启动)cuCtxPopCurrent(&ctx);          // 弹出上下文cuCtxDestroy(ctx);              // 销毁上下文
      }
      2)共享上下文模式‌
      主线程创建上下文,其他线程通过同步机制安全共享。
      // 全局变量
      CUcontext g_ctx;
      std::mutex g_ctx_mutex;// 主线程初始化
      cuCtxCreate(&g_ctx, 0, device);// 子线程操作
      void thread_func() {std::lock_guard<std::mutex> lock(g_ctx_mutex);  // 互斥锁保护cuCtxPushCurrent(g_ctx);        // 压入共享上下文// 执行CUDA操作CUcontext popped;cuCtxPopCurrent(&popped);       // 弹出上下文
      }

三、同步策略

  1. 主机端多线程同步

    • 锁保护非线程安全API‌:CUDA上下文操作(如cudaMemcpycudaMalloc)需通过互斥锁(如std::mutex)保护,避免多线程竞争导致未定义行为‌。
    • 独立设备上下文‌:多进程或多线程可各自绑定独立GPU设备(cudaSetDevice()),减少资源争用‌。
  2. 设备端高效同步

    • 原子操作‌:通过atomicAddatomicExch等函数实现全局变量的线程安全更新,避免数据竞争‌。
    • 流与事件同步‌:
      • 流内顺序执行‌:同一CUDA流中的操作按提交顺序执行,通过cudaStreamSynchronize()等待流完成‌。
      • 事件跨流协调‌:使用cudaEventRecord()记录事件,通过cudaStreamWaitEvent()实现流间依赖‌。

四、性能优化

  1. 最小化同步开销

    • 避免频繁调用__syncthreads(),仅在关键数据依赖处同步‌。
    • 使用异步操作(如cudaMemcpyAsync)重叠数据传输与计算,隐藏延迟‌。
  2. 共享内存优化

    • 共享内存访问需对齐以减少bank冲突,提升访存效率‌。
    • 利用共享内存缓存重复访问的全局数据,降低延迟‌。
  3. 协助组

    • 协作组提供更灵活的线程同步机制,支持动态线程组划分(如warp、块、网格级):
      #include <cooperative_groups.h>
      using namespace cooperative_groups;grid_group grid = this_grid();
      grid.sync(); // 网格级同步
      此特性需GPU架构支持(如Compute Capability 6.0+),适用于大规模并行任务调度‌。

http://www.ppmy.cn/devtools/168016.html

相关文章

初阶数据结构(C语言实现)——5.3 堆的应用(1)——堆排序

目录 1 堆的应用1.1 堆排序1.1.1 思路1.1.2 代码实现 1.2 建堆的时间复杂度1.2.1 向下调整1.2.1 向上调整1.2.3 结论 学习堆的应用之前&#xff0c;欢迎学习下堆。 这是博主之前的文章&#xff0c;欢迎学习交流 初阶数据结构&#xff08;C语言实现&#xff09;——5.2 二叉树的…

langchain如何并行调用运行接口

文章目录 概要并行化步骤 概要 RunnableParallel 原语本质上是一个字典&#xff0c;其值是运行接口&#xff08;或可以被强制转换为运行接口的事物&#xff0c;如函数&#xff09;。它并行运行所有值&#xff0c;并且每个值都使用 RunnableParallel 的整体输入进行调用。最终返…

RabbitMQ相关的面试题

以下是150道RabbitMQ相关的面试题及简洁回答&#xff1a; RabbitMQ基础概念 1. 什么是RabbitMQ&#xff1f; RabbitMQ是一个开源的AMQP&#xff08;高级消息队列协议&#xff09;实现&#xff0c;用于在分布式系统中进行消息传递和通信。它允许应用程序通过网络发送和接收消息…

SpringBoot集成ElasticSearch实现支持错别字检索和关键字高亮的模糊查询

文章目录 一、背景二、环境准备1.es8集群2.Kibana3.Canal 三、集成到SpringBoot1.新增依赖2.es配置类3.建立索引4.修改查询方法 四、修改前端 一、背景 我们在开发项目的搜索引擎的时候&#xff0c;如果当数据量庞大、同时又需要支持全文检索模糊查询&#xff0c;甚至你想做到…

【创作者纪念日1460天4年】我的创作纪念日

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(6)

1.问题描述&#xff1a; 使用华为内置的MapComponent&#xff0c; 发现显示不出来。查看日志&#xff0c; MapRender底层有报错。 解决方案&#xff1a; 麻烦按以下步骤检查下地图服务&#xff0c;特别是签名证书指纹那部分。 1.一般没有展示地图&#xff0c;可能和没有配置…

【视频】SRS将RTMP转WebRTC、HLS流;获取RTSP转其它流

1、安装依赖库 sudo apt install tclsh sudo apt install cmake sudo apt install autotools-dev automake m4 perl sudo apt install libtool2、源码安装 1)下载源码 https://github.com/ossrs/srs/releases/tag/v5.0-r32)配置、编译 ./configure && make -j83、…

【C++】:C++11详解 —— 入门基础

目录 C11简介 统一的列表初始化 1.初始化范围扩展 2.禁止窄化转换&#xff08;Narrowing Conversion&#xff09; 3.解决“最令人烦恼的解析”&#xff08;Most Vexing Parse&#xff09; 4.动态数组初始化 5. 直接初始化返回值 总结 声明 1.auto 类型推导 2. declty…