zoukankan      html  css  js  c++  java
  • (转)CUDA软件架构—网格(Grid)、线程块(Block)和线程(Thread)的组织关系以及线程索引的计算公式

    转自:https://blog.csdn.net/dcrmg/article/details/54867507


     

    网格(Grid)、线程块(Block)和线程(Thread)的组织关系

     
    CUDA的软件架构由网格(Grid)、线程块(Block)和线程(Thread)组成,相当于把GPU上的计算单元分为若干(2~3)个网格,每个网格内包含若干(65535)个线程块,每个线程块包含若干(512)个线程,三者的关系如下图:

    Thread,block,grid是CUDA编程上的概念,为了方便程序员软件设计,组织线程。

    • thread:一个CUDA的并行程序会被以许多个threads来执行。
    • block:数个threads会被群组成一个block,同一个block中的threads可以同步,也可以通过shared memory通信。
    • grid:多个blocks则会再构成grid。
     

    网格(Grid)、线程块(Block)和线程(Thread)的最大数量

     
    CUDA中可以创建的网格数量跟GPU的计算能力有关,可创建的Grid、Block和Thread的最大数量参看以下表格:
     
     
    在单一维度上,程序的执行可以由多达3*65535*512=100661760(一亿)个线程并行执行,这对在CPU上创建并行线程来说是不可想象的。
     

    线程索引的计算公式

     
    一个Grid可以包含多个Blocks,Blocks的组织方式可以是一维的,二维或者三维的。block包含多个Threads,这些Threads的组织方式也可以是一维,二维或者三维的。
    CUDA中每一个线程都有一个唯一的标识ID—ThreadIdx,这个ID随着Grid和Block的划分方式的不同而变化,这里给出Grid和Block不同划分方式下线程索引ID的计算公式。
     
    1、 grid划分成1维,block划分为1维

        int threadId = blockIdx.x *blockDim.x + threadIdx.x;  
        
      
    2、 grid划分成1维,block划分为2维  

        int threadId = blockIdx.x * blockDim.x * blockDim.y+ threadIdx.y * blockDim.x + threadIdx.x;  
      
      
    3、 grid划分成1维,block划分为3维  

        int threadId = blockIdx.x * blockDim.x * blockDim.y * blockDim.z  
                           + threadIdx.z * blockDim.y * blockDim.x  
                           + threadIdx.y * blockDim.x + threadIdx.x;  

      
    4、 grid划分成2维,block划分为1维  

        int blockId = blockIdx.y * gridDim.x + blockIdx.x;  
        int threadId = blockId * blockDim.x + threadIdx.x;  
       
      
    5、 grid划分成2维,block划分为2维 

        int blockId = blockIdx.x + blockIdx.y * gridDim.x;  
        int threadId = blockId * (blockDim.x * blockDim.y)  
                           + (threadIdx.y * blockDim.x) + threadIdx.x;  
        
      
    6、 grid划分成2维,block划分为3维

        int blockId = blockIdx.x + blockIdx.y * gridDim.x;  
        int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)  
                           + (threadIdx.z * (blockDim.x * blockDim.y))  
                           + (threadIdx.y * blockDim.x) + threadIdx.x;  
       
      
    7、 grid划分成3维,block划分为1维 

        int blockId = blockIdx.x + blockIdx.y * gridDim.x  
                         + gridDim.x * gridDim.y * blockIdx.z;  
        int threadId = blockId * blockDim.x + threadIdx.x;  
       
      
    8、 grid划分成3维,block划分为2维  

        int blockId = blockIdx.x + blockIdx.y * gridDim.x  
                         + gridDim.x * gridDim.y * blockIdx.z;  
        int threadId = blockId * (blockDim.x * blockDim.y)  
                           + (threadIdx.y * blockDim.x) + threadIdx.x;  
       
      
    9、 grid划分成3维,block划分为3维

        int blockId = blockIdx.x + blockIdx.y * gridDim.x  
                         + gridDim.x * gridDim.y * blockIdx.z;  
        int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)  
                           + (threadIdx.z * (blockDim.x * blockDim.y))  
                           + (threadIdx.y * blockDim.x) + threadIdx.x;     
  • 相关阅读:
    矩阵特征值和椭圆长短轴的关系?
    Harris角点检测原理详解
    SIFT特征提取分析
    Sift中尺度空间、高斯金字塔、差分金字塔(DOG金字塔)、图像金字塔
    图像处理与计算机视觉的经典书籍
    霍夫变换
    熔断原理与实现Golang版
    如何利用go-zero在Go中快速实现JWT认证
    如何让服务在流量暴增的情况下保持稳定输出
    企业级RPC框架zRPC
  • 原文地址:https://www.cnblogs.com/xiaouisme/p/13936618.html
Copyright © 2011-2022 走看看