色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

介紹CUDA編程模型及CUDA線程體系

冬至子 ? 來源:指北筆記 ? 作者:張北北 ? 2023-05-19 11:32 ? 次閱讀

可伸縮的編程模型

CUDA 編程模型主要有三個關鍵抽象:層級的線程組,共享內存和柵同步(barrier synchronization)。

這些抽象提供了細粒度的數據并行和線程并行,可以以嵌套在粗粒的數據并行和任務并行中。它們鼓勵將問題分解為子問題。每個子問題可以獨立的在block threads中并行解決。同時每個子問題分成更細的部分,可以由塊中的所有線程并行地合作解決。

這種分解通過允許線程在解決每個子問題時進行協作來保留語言的表達性,同時支持自動可伸縮性。實際上,每個線程塊都可以在GPU中任何可用的多處理器上調度,以任何順序、并發或順序,因此編譯的CUDA程序可以在任意數量的多處理器上執行,如圖所示,而且只有運行時系統需要知道物理多處理器的數量。

圖片

圖1 Automatic Scalability

Note: A GPU is built around an array of Streaming Multiprocessors (SMs) (see Hardware Implementation for more details). A multithreaded program is partitioned into blocks of threads that execute independently from each other, so that a GPU with more multiprocessors will automatically execute the program in less time than a GPU with fewer multiprocessors.

Kernels

CUDA c++ 通過允許程序員定義 c++ 函數( 稱為kernel )來擴展 c++,當調用這些函數時,由 N 個不同的 CUDA 線程并行執行 N 次,而不是像常規 c++ 函數那樣只執行一次。

使用_ global _ 聲明說明符定義內核,并使用新的<<<…>>>執行配置語法(參見c++語言擴展)。每個執行內核的線程都有一個惟一的線程ID,可以在內核中通過內置變量訪問該ID。

下面的示例代碼使用內置變量 threadIdx ,將兩個大小為N的向量A和B相加,并將結果存儲到向量C中:

// Kernel definition
__global__ void VecAdd(float* A, float* B, float* C)
{
    int i = threadIdx.x;
    C[i] = A[i] + B[i];
}

int main()
{
    ...
    // Kernel invocation with N threads
    VecAdd<<<1, N>>>(A, B, C);
    ...
}

執行VecAdd()的N個線程中的每一個都執行一次成對的相加。

Thread Hierarchy

為了方便起見,threadIdx 是一個三分量的向量,因此可以使用一維、二維或三維線程索引來標識線程,從而形成一維、二維或三維線程塊,稱為線程塊。這提供了一種很自然的方法來調用跨域元素(如向量、矩陣或體)的計算。

線程的索引和線程 ID 以一種直接的方式相互關聯:

  • 對于一維塊,它們是相同的
  • 對于大小為(Dx, Dy)的二維塊,索引為(x, y)的線程ID為(x + y Dx);
  • 對于大小為Dx, Dy, Dz的三維塊,索引為(x, y, z)的線程ID為(x + y Dx + z Dx Dy)。

例如,下面的代碼將兩個大小為NxN的矩陣A和B相加,并將結果存儲到矩陣C中:

// Kernel definition
__global__ void MatAdd(float A[N][N], float B[N][N],
                       float C[N][N])
{
    int i = threadIdx.x;
    int j = threadIdx.y;
    C[i][j] = A[i][j] + B[i][j];
}

int main()
{
    ...
    // Kernel invocation with one block of N * N * 1 threads
    int numBlocks = 1;
    dim3 threadsPerBlock(N, N);
    MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
    ...
}

每個塊的線程數量是有限制的,因為一個塊的所有線程都駐留在同一個流多處理器核心上,必須共享該核心的有限內存資源。 在當前的gpu上,一個線程塊可能包含多達1024個線程

但是,一個內核可以由多個形狀相同的線程塊執行,這樣 線程總數就等于每個塊的線程數乘以塊的數量

塊被組織成一維、二維或三維的線程塊網格,如圖所示。 網格中線程塊的數量通常由正在處理的數據的大小決定 ,數據的大小通常超過系統中處理器的數量。

圖片

圖2 Grid of Thread Blocks

每個塊的線程數和每個網格的塊數在<<<…>>>語法的類型可以是int或dim3。二維塊或網格可以像上面的例子中那樣指定。

網格中的每個塊都可以通過一個一維、二維或三維的惟一索引來標識。該索引可以通過內核中內置的blockIdx變量訪問。 線程塊的維度可以在內核中通過內置的blockDim變量訪問

擴展前面的MatAdd()示例以處理多個塊,代碼如下所示。

// Kernel definition
__global__ void MatAdd(float A[N][N], float B[N][N],
float C[N][N])
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    int j = blockIdx.y * blockDim.y + threadIdx.y;
    if (i < N && j < N)
        C[i][j] = A[i][j] + B[i][j];
}

int main()
{
    ...
    // Kernel invocation
    dim3 threadsPerBlock(16, 16);
    dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);
    MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
    ...
}

線程塊大小為16x16(256個線程),雖然在本例中是任意的,但卻是常見的選擇 。網格是用足夠的塊創建的,每個矩陣元素都有一個線程。

為了簡單起見,本示例假設每個維度中每個網格的線程數可以被該維度中每個塊的線程數整除,盡管事實并非如此。

線程塊需要獨立執行 :必須能夠以任何順序執行它們,并行或串行。這種獨立性要求允許線程塊在任意數量的核上以任意順序調度,如圖1所示,這使程序員能夠編寫隨核數量擴展的代碼。

塊中的線程可以通過共享內存共享數據,并通過同步它們的執行來協調內存訪問,從而進行協作 。更精確地說,可以通過調用__syncthreads()內部函數來指定內核中的同步點;__syncthreads()充當一個屏障,在允許任何線程繼續之前,塊中的所有線程都必須等待。除了__syncthreads()之外,Cooperative Groups API還提供了一組豐富的線程同步原語。

為了高效合作,共享內存應該是每個處理器核心附近的低延遲內存(很像L1緩存),并且__syncthreads()應該是輕量級的。

Thread Block Clusters

隨著NVIDIA Compute Capability 9.0的引入 ,CUDA編程模型引入了一個可選的層次結構級別,稱為 線程塊集群,它由線程塊組成與線程塊中的線程被保證在流多處理器上同步調度類似,集群中的線程塊也被保證在GPU中的GPU處理集群(GPC)上同步調度

與線程塊類似,集群也被組織成一維、二維或三維,如圖3所示。一個集群中的線程塊數量可以由用戶定義, CUDA支持一個集群中最多8個線程塊作為可移植的集群大小 。線程塊集群大小是否超過8取決于體系結構,可以使用cudaoccuancymaxpotentialclustersize API進行查詢。

圖片

圖3 Grid of Thread Block Clusters

Note: In a kernel launched using cluster support, the gridDim variable still denotes the size in terms of number of thread blocks , for compatibility purposes. The rank of a block in a cluster can be found using the Cluster Group API.

線程塊集群可以在內核中使用編譯器時間內核屬性__cluster_dims__(X,Y,Z)或使用CUDA內核啟動API cudaLaunchKernelEx來啟用。下面的示例展示了如何使用編譯器時間內核屬性啟動集群。使用內核屬性的集群大小在編譯時固定,然后可以使用經典的<<<,>>>啟動內核。如果內核使用編譯時集群大小,則在啟動內核時無法修改集群大小。

  • 編譯期指定
// Kernel definition
// Compile time cluster size 2 in X-dimension and 1 in Y and Z dimension
__global__ void __cluster_dims__(2, 1, 1) cluster_kernel(float *input, float* output)
{

}

int main()
{
    float *input, *output;
    // Kernel invocation with compile time cluster size
    dim3 threadsPerBlock(16, 16);
    dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);

    // The grid dimension is not affected by cluster launch, and is still enumerated
    // using number of blocks. 
    // The grid dimension must be a multiple of cluster size.
    cluster_kernel<<
  • 運行期指定

線程塊集群大小也可以在運行時設置,并且可以使用CUDA內核啟動API cudaLaunchKernelEx啟動內核。下面的代碼示例展示了如何使用可擴展API啟動集群內核。

// Kernel definition
// No compile time attribute attached to the kernel
__global__ void cluster_kernel(float *input, float* output)
{
  
}

int main()
{
    float *input, *output;
    dim3 threadsPerBlock(16, 16);
    dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);
    cluster_kernel<<

在具有9.0計算能力的GPU中,集群中的所有線程塊都被保證在單個GPU處理集群(GPC)上共同調度,并允許集群中的線程塊使用cluster Group API cluster.sync()執行硬件支持的同步 。集群組還提供了成員函數,分別使用num_threads()和num_blocks() API根據線程數或塊數查詢集群組的大小。可以分別通過dim_threads()和dim_blocks() API查詢集群組中線程或塊的級別。

屬于一個集群的線程塊可以訪問 分布式共享內存 。集群中的線程塊能夠對分布式共享內存中的任何地址進行讀、寫和執行原子操作。分布式共享內存給出了一個在分布式共享內存中執行直方圖的示例。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 多處理器
    +關注

    關注

    0

    文章

    22

    瀏覽量

    8945
  • C++語言
    +關注

    關注

    0

    文章

    147

    瀏覽量

    6993
  • CUDA
    +關注

    關注

    0

    文章

    121

    瀏覽量

    13638
收藏 人收藏

    評論

    相關推薦

    CUDA編程教程

    Nvidia CUDA 2.0編程教程
    發表于 03-05 07:30

    LInux安裝cuda sdk

    1.安裝toolkit(1)cd /home/CUDA_train/software/cuda4.1(2)./cudatoolkit_4.1.28_linux_64_rhel6.x.run
    發表于 07-24 06:11

    CUDA教程之Linux系統下CUDA安裝教程

    CUDA教程之1:Linux系統下CUDA安裝教程
    發表于 06-02 16:53

    什么是CUDA

    的時間盡可能清晰的了解這個深度學習賴以實現的基礎概念。本文在以下資料的基礎上整理完成,感謝以下前輩提供的資料:CUDA——“從入門到放棄”我的CUDA學習之旅——啟程介紹一篇不錯的CUDA
    發表于 07-26 06:28

    什么是CUDA

    什么是CUDA
    發表于 09-28 07:37

    cuda程序設計

      •GPGPU及CUDA介紹   •CUDA編程模型   •多
    發表于 11-12 16:12 ?0次下載

    CUDA 6中的統一內存模型

    NVIDIA在CUDA 6中引入了統一內存模型 ( Unified Memory ),這是CUDA歷史上最重要的編程模型改進之一。在當今典型
    的頭像 發表于 07-02 14:08 ?2818次閱讀

    并行計算平臺和NVIDIA編程模型CUDA的更簡單介紹

      這篇文章是對 CUDA 的一個超級簡單的介紹,這是一個流行的并行計算平臺和 NVIDIA 的編程模型。我在 2013 年給 CUDA
    的頭像 發表于 04-11 09:46 ?1444次閱讀
    并行計算平臺和NVIDIA<b class='flag-5'>編程</b><b class='flag-5'>模型</b><b class='flag-5'>CUDA</b>的更簡單<b class='flag-5'>介紹</b>

    CUDA并行計算平臺的C/C++接口的簡單介紹

    CUDA 編程模型是一個異構模型,其中使用了 CPU 和 GPU 。在 CUDA 中, host 指的是 CPU 及其存儲器, device
    的頭像 發表于 04-11 10:13 ?1664次閱讀

    CUDA簡介: CUDA編程模型概述

    CUDA 編程模型中,線程是進行計算或內存操作的最低抽象級別。 從基于 NVIDIA Ampere GPU 架構的設備開始,CUDA
    的頭像 發表于 04-20 17:16 ?3007次閱讀
    <b class='flag-5'>CUDA</b>簡介: <b class='flag-5'>CUDA</b><b class='flag-5'>編程</b><b class='flag-5'>模型</b>概述

    CUDA編程模型如何在c++實現

      NVIDIA GPU 架構圍繞可擴展的多線程流式多處理器 (SM: Streaming Multiprocessors) 陣列構建。當主機 CPU 上的 CUDA 程序調用內核網格時,網格的塊被
    的頭像 發表于 04-21 16:13 ?1501次閱讀
    <b class='flag-5'>CUDA</b><b class='flag-5'>編程</b><b class='flag-5'>模型</b>如何在c++實現

    如何使用CUDA使warp級編程安全有效

      NVIDIA GPUs 以 SIMT (單指令,多線程)方式執行稱為 warps 的線程組。許多 CUDA 程序通過利用 warp 執行來獲得高性能。在這個博客中,我們將展示如何使用 CU
    的頭像 發表于 04-28 16:09 ?2938次閱讀
    如何使用<b class='flag-5'>CUDA</b>使warp級<b class='flag-5'>編程</b>安全有效

    CUDA矩陣乘法優化手段詳解

    單精度矩陣乘法(SGEMM)幾乎是每一位學習 CUDA 的同學繞不開的案例,這個經典的計算密集型案例可以很好地展示 GPU 編程中常用的優化技巧。本文將詳細介紹 CUDA SGEMM
    的頭像 發表于 09-28 09:46 ?1928次閱讀

    使用CUDA進行編程的要求有哪些

    CUDA是NVIDIA的一種用于GPU編程的技術,CUDA核心是GPU上的一組小型計算單元,它們可以同時執行大量的計算任務。
    的頭像 發表于 01-08 09:20 ?2544次閱讀

    CUDA核心是什么?CUDA核心的工作原理

    CUDA核心(Compute Unified Device Architecture Core)是NVIDIA圖形處理器(GPU)上的計算單元,用于執行并行計算任務。每個CUDA核心可以執行單個線程的指令,包括算術運算、邏輯操作
    發表于 09-27 09:38 ?8746次閱讀
    <b class='flag-5'>CUDA</b>核心是什么?<b class='flag-5'>CUDA</b>核心的工作原理
    主站蜘蛛池模板: 欧美18videosex性欧美老师| 久久中文字幕免费视频| 回复术士人生重启在线观看| 色www.亚洲免费视频| 97在线免费观看| 乱叫抽搐流白浆免费视频| 一个人的视频全免费在线观看www 一个人的免费完整在线观看HD | 簧片免费观看| 亚洲欧美激情精品一区二区| 国产精品一久久香蕉国产线看| 色婷婷我要去我去也| 顶级少妇AAAAABBBBB片| 三级网址在线| 国产乱码卡二卡三卡4W| 污文啊好棒棒啊好了| 国产亚洲精品久久久久久久| 亚洲刺激视频| 久久囯产精品777蜜桃传媒| 友田真希息与子中文字幕| 久久综合香蕉久久久久久久| 97视频免费观看| 青青视频国产色偷偷| 国产成A人片在线观看| 午夜十八岁禁| 九九电影伦理片| 中国二级毛片| 欧美性猛交AAA片| 国产精品99久久久久久AV下载| 亚洲AV综合99一二三四区| 九九热综合| AV多人爱爱XXx| 思思99精品国产自在现线| 狠狠干女人| 91se在线看片国产免费观看| 日韩免费一区| 国产午夜久久影院| 孕妇泬出白浆18P| 日本黄色www| 嘿嘿视频在线观看 成人| 2020亚洲色噜噜狠狠网站| 日日日操操操|