0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內(nèi)不再提示

CUDA編程模型如何在c++實現(xiàn)

星星科技指導(dǎo)員 ? 來源:NVIDIA ? 作者:Ken He ? 2022-04-21 16:13 ? 次閱讀

本章通過概述CUDA編程模型是如何在c++中公開的,來介紹CUDA的主要概念。

NVIDIA GPU 架構(gòu)圍繞可擴展的多線程流式多處理器 (SM: Streaming Multiprocessors) 陣列構(gòu)建。當主機 CPU 上的 CUDA 程序調(diào)用內(nèi)核網(wǎng)格時,網(wǎng)格的塊被枚舉并分發(fā)到具有可用執(zhí)行能力的多處理器。一個線程塊的線程在一個SM上并發(fā)執(zhí)行,多個線程塊可以在一個SM上并發(fā)執(zhí)行。當線程塊終止時,新塊在空出的SM上啟動。

SM旨在同時執(zhí)行數(shù)百個線程。為了管理如此大量的線程,它采用了一種稱為 SIMT(Single-Instruction, Multiple-Thread: 單指令,多線程)的獨特架構(gòu),在 SIMT 架構(gòu)中進行了描述。這些指令是流水線的,利用單個線程內(nèi)的指令級并行性,以及通過同時硬件多線程處理的廣泛線程級并行性,如硬件多線程中詳述。與 CPU 內(nèi)核不同,它們是按順序發(fā)出的,沒有分支預(yù)測或推測執(zhí)行。

SIMT 架構(gòu)和硬件多線程描述了所有設(shè)備通用的流式多處理器的架構(gòu)特性。 Compute Capability 3.x、Compute Capability 5.x、Compute Capability 6.x 和 Compute Capability 7.x 分別為計算能力 3.x、5.x、6.x 和 7.x 的設(shè)備提供了詳細信息。

NVIDIA GPU 架構(gòu)使用 little-endian 表示。

4.1 SIMT 架構(gòu)

多處理器以 32 個并行線程組(稱為 warp)的形式創(chuàng)建、管理、調(diào)度和執(zhí)行線程。組成 warp 的各個線程一起從同一個程序地址開始,但它們有自己的指令地址計數(shù)器和寄存器狀態(tài),因此可以自由地分支和獨立執(zhí)行。warp一詞源于編織,這是第一個并行線程技術(shù)。半warp是warp的前半部分或后半部分。四分之一經(jīng)線是warp的第一、第二、第三或第四四分之一。

當一個多處理器被賦予一個或多個線程塊來執(zhí)行時,它將它們劃分為warp,并且每個warp都由warp調(diào)度程序調(diào)度以執(zhí)行。一個塊被分割成warp的方式總是一樣的;每個warp包含連續(xù)的線程,增加線程ID,第一個warp包含線程0。線程層次結(jié)構(gòu)描述了線程ID如何與塊中的線程索引相關(guān)。

一個 warp 一次執(zhí)行一條公共指令,因此當一個 warp 的所有 32 個線程都同意它們的執(zhí)行路徑時,就可以實現(xiàn)完全的效率。如果 warp 的線程通過依賴于數(shù)據(jù)的條件分支發(fā)散,則 warp 執(zhí)行所采用的每個分支路徑,禁用不在該路徑上的線程。分支分歧只發(fā)生在一個warp內(nèi);不同的 warp 獨立執(zhí)行,無論它們是執(zhí)行公共的還是不相交的代碼路徑。

SIMT 體系結(jié)構(gòu)類似于 SIMD(單指令多數(shù)據(jù))向量組織,其中單指令控制多個處理元素。一個關(guān)鍵區(qū)別是 SIMD 矢量組織向軟件公開了 SIMD 寬度,而 SIMT 指令指定單個線程的執(zhí)行和分支行為。與 SIMD 向量機相比,SIMT 使程序員能夠為獨立的標量線程編寫線程級并行代碼,以及為協(xié)調(diào)線程編寫數(shù)據(jù)并行代碼。為了正確起見,程序員基本上可以忽略 SIMT 行為;但是,通過代碼很少需要warp中的線程發(fā)散,可以實現(xiàn)顯著的性能改進。在實踐中,這類似于傳統(tǒng)代碼中緩存線的作用:在設(shè)計正確性時可以安全地忽略緩存線大小,但在設(shè)計峰值性能時必須在代碼結(jié)構(gòu)中考慮。另一方面,向量架構(gòu)需要軟件將負載合并到向量中并手動管理分歧。

在 Volta 之前,warp 使用在 warp 中的所有 32 個線程之間共享的單個程序計數(shù)器以及指定 warp 的活動線程的活動掩碼。結(jié)果,來自不同區(qū)域或不同執(zhí)行狀態(tài)的同一warp的線程無法相互發(fā)送信號或交換數(shù)據(jù),并且需要細粒度共享由鎖或互斥鎖保護的數(shù)據(jù)的算法很容易導(dǎo)致死鎖,具體取決于來自哪個warp競爭線程。

從 Volta 架構(gòu)開始,獨立線程調(diào)度允許線程之間的完全并發(fā),而不管 warp。使用獨立線程調(diào)度,GPU 維護每個線程的執(zhí)行狀態(tài),包括程序計數(shù)器和調(diào)用堆棧,并且可以在每個線程的粒度上產(chǎn)生執(zhí)行,以便更好地利用執(zhí)行資源或允許一個線程等待數(shù)據(jù)由他人生產(chǎn)。調(diào)度優(yōu)化器確定如何將來自同一個 warp 的活動線程組合成 SIMT 單元。這保留了與先前 NVIDIA GPU 一樣的 SIMT 執(zhí)行的高吞吐量,但具有更大的靈活性:線程現(xiàn)在可以在 sub-warp 粒度上發(fā)散和重新收斂。

如果開發(fā)人員對先前硬件架構(gòu)的 warp-synchronicity2 做出假設(shè),獨立線程調(diào)度可能會導(dǎo)致參與執(zhí)行代碼的線程集與預(yù)期的完全不同。特別是,應(yīng)重新訪問任何warp同步代碼(例如無同步、內(nèi)部warp減少),以確保與 Volta 及更高版本的兼容性。有關(guān)詳細信息,請參閱計算能力 7.x。

注意:

參與當前指令的 warp 線程稱為活動線程,而不在當前指令上的線程是非活動的(禁用)。線程可能由于多種原因而處于非活動狀態(tài),包括比其 warp 的其他線程更早退出,采用與 warp 當前執(zhí)行的分支路徑不同的分支路徑,或者是線程數(shù)不是線程數(shù)的塊的最后一個線程warp尺寸的倍數(shù)。

如果 warp 執(zhí)行的非原子指令為多個 warp 的線程寫入全局或共享內(nèi)存中的同一位置,則該位置發(fā)生的序列化寫入次數(shù)取決于設(shè)備的計算能力(參見 Compute Capability 3.x、Compute Capability 5.x、Compute Capability 6.x 和 Compute Capability 7.x),哪個線程執(zhí)行最終寫入是未定義的。

如果一個由 warp 執(zhí)行的原子指令讀取、修改和寫入全局內(nèi)存中多個線程的同一位置,則對該位置的每次讀取/修改/寫入都會發(fā)生并且它們都被序列化,但是它們發(fā)生的順序是不確定的。

4.2 硬件多線程

多處理器處理的每個 warp 的執(zhí)行上下文(程序計數(shù)器、寄存器等)在 warp 的整個生命周期內(nèi)都在芯片上維護。因此,從一個執(zhí)行上下文切換到另一個執(zhí)行上下文是沒有成本的,并且在每個指令發(fā)出時,warp 調(diào)度程序都會選擇一個線程準備好執(zhí)行其下一條指令(warp 的活動線程)并將指令發(fā)布給這些線程。

特別是,每個多處理器都有一組 32 位寄存器,這些寄存器在 warp 之間進行分區(qū),以及在線程塊之間進行分區(qū)的并行數(shù)據(jù)緩存或共享內(nèi)存。

對于給定內(nèi)核,可以在多處理器上一起駐留和處理的塊和warp的數(shù)量取決于內(nèi)核使用的寄存器和共享內(nèi)存的數(shù)量以及多處理器上可用的寄存器和共享內(nèi)存的數(shù)量。每個多處理器也有最大數(shù)量的駐留塊和駐留warp的最大數(shù)量。這些限制以及多處理器上可用的寄存器數(shù)量和共享內(nèi)存是設(shè)備計算能力的函數(shù),在附錄計算能力中給出。如果每個多處理器沒有足夠的寄存器或共享內(nèi)存來處理至少一個塊,內(nèi)核將無法啟動。

一個塊中的warp總數(shù)如下:

pYYBAGJhEkOAPzJ8AABJQgzZJ1g200.png

為塊分配的寄存器總數(shù)和共享內(nèi)存總量記錄在 CUDA 工具包中提供的 CUDA Occupancy Calculator中。

關(guān)于作者

Ken He 是 NVIDIA 企業(yè)級開發(fā)者社區(qū)經(jīng)理 & 高級講師,擁有多年的 GPU 和人工智能開發(fā)經(jīng)驗。自 2017 年加入 NVIDIA 開發(fā)者社區(qū)以來,完成過上百場培訓(xùn),幫助上萬個開發(fā)者了解人工智能和 GPU 編程開發(fā)。在計算機視覺,高性能計算領(lǐng)域完成過多個獨立項目。并且,在機器人無人機領(lǐng)域,有過豐富的研發(fā)經(jīng)驗。對于圖像識別,目標的檢測與跟蹤完成過多種解決方案。曾經(jīng)參與 GPU 版氣象模式GRAPES,是其主要研發(fā)者。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 機器人
    +關(guān)注

    關(guān)注

    210

    文章

    27994

    瀏覽量

    205551
  • NVIDIA
    +關(guān)注

    關(guān)注

    14

    文章

    4816

    瀏覽量

    102633
  • gpu
    gpu
    +關(guān)注

    關(guān)注

    27

    文章

    4632

    瀏覽量

    128442
收藏 人收藏

    評論

    相關(guān)推薦

    C++實現(xiàn)類似instanceof的方法

    函數(shù),可實際上C++中沒有。但是別著急,其實C++中有兩種簡單的方法可以實現(xiàn)類似Java中的instanceof的功能。 在 C++ 中,確定對象的類型是
    的頭像 發(fā)表于 07-18 10:16 ?436次閱讀
    <b class='flag-5'>C++</b>中<b class='flag-5'>實現(xiàn)</b>類似instanceof的方法

    FX2 CY7C68013A如何在C++環(huán)境中使用LoadEEPROM函數(shù)?

    我使用的是 FX2 CY7C68013A 芯片。 我知道 CyUSB.NET 庫中有我需要的 LoadEEPROM 函數(shù)。 請問如何在 C++ 環(huán)境而不是 C#/CLR 環(huán)境中使用該函
    發(fā)表于 05-31 06:59

    c語言,c++,java,python區(qū)別

    C語言、C++、Java和Python是四種常見的編程語言,各有優(yōu)點和特點。 C語言: C語言是一種面向過程的
    的頭像 發(fā)表于 02-05 14:11 ?1644次閱讀

    vb語言和c++語言的區(qū)別

    VB語言和C++語言是兩種不同的編程語言,雖然它們都屬于高級編程語言,但在設(shè)計和用途上有很多區(qū)別。下面將詳細比較VB語言和C++語言的區(qū)別。 設(shè)計目標: VB語言(Visual Bas
    的頭像 發(fā)表于 02-01 10:20 ?1793次閱讀

    C++簡史:C++是如何開始的

    的 MISRA C++:2023 博客系列的第二部分。 在這篇博客中,我們將深入探討 C++ 的歷史、編程語言多年來的發(fā)展歷程以及它的下一步發(fā)展方向。
    的頭像 發(fā)表于 01-11 09:00 ?485次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的

    【飛騰派4G版免費試用】第五章:使用C++部署tflite模型到飛騰派

    本章記錄下使用 C++ 進行佩奇檢測 tflite 模型推理的過程。
    的頭像 發(fā)表于 12-28 09:08 ?1117次閱讀
    【飛騰派4G版免費試用】第五章:使用<b class='flag-5'>C++</b>部署tflite<b class='flag-5'>模型</b>到飛騰派

    OpenCV4.8 CUDA編程代碼教程

    OpenCV4支持通過GPU實現(xiàn)CUDA加速執(zhí)行,實現(xiàn)對OpenCV圖像處理程序的加速運行,當前支持加速的模塊包括如下。
    的頭像 發(fā)表于 12-05 09:56 ?911次閱讀
    OpenCV4.8 <b class='flag-5'>CUDA</b><b class='flag-5'>編程</b>代碼教程

    c++怎么開始編程

    C++是一種高級的、通用的編程語言,用于開發(fā)各種類型的應(yīng)用程序。它是從C語言演變而來,也是一種靜態(tài)類型語言,可以在不同的平臺上進行開發(fā)。C++具有高度的靈活性和性能,并且廣泛應(yīng)用于游戲
    的頭像 發(fā)表于 11-27 15:56 ?824次閱讀

    使用Visual C++進行串口通信編程

    電子發(fā)燒友網(wǎng)站提供《使用Visual C++進行串口通信編程.doc》資料免費下載
    發(fā)表于 11-21 09:39 ?3次下載
    使用Visual <b class='flag-5'>C++</b>進行串口通信<b class='flag-5'>編程</b>

    如何使用OpenVINO C++ API部署FastSAM模型

    象的位置和邊界。本文將介紹如何使用 OpenVINO C++ API 部署 FastSAM 模型,以實現(xiàn)快速高效的語義分割。在前文中我們發(fā)表了《基于 OpenVINO Python API 部署
    的頭像 發(fā)表于 11-17 09:53 ?784次閱讀
    如何使用OpenVINO <b class='flag-5'>C++</b> API部署FastSAM<b class='flag-5'>模型</b>

    探索C++編程習慣與編程要點

    C++的類可以分為帶指針數(shù)據(jù)成員與不帶指針數(shù)據(jù)成員兩類,complex就屬于不帶指針成員的類。而這里要說的字符串類String,一般的實現(xiàn)會帶有一個char *指針。帶指針數(shù)據(jù)成員的類,需要自己實現(xiàn)class三大件:拷貝構(gòu)造函數(shù)
    的頭像 發(fā)表于 11-14 09:25 ?357次閱讀
    探索<b class='flag-5'>C++</b>的<b class='flag-5'>編程</b>習慣與<b class='flag-5'>編程</b>要點

    Linux C/C++編程中的內(nèi)存泄漏問題

    ,需要對各種編程語言和技術(shù)有深入的理解。而C++,作為一種高性能的編程語言,在許多領(lǐng)域(如網(wǎng)絡(luò)編程、嵌入式系統(tǒng)、音視頻處理等)都發(fā)揮著不可忽視的作用。然而,許多
    的頭像 發(fā)表于 11-09 10:11 ?920次閱讀
    Linux <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>編程</b>中的內(nèi)存泄漏問題

    基于OpenVINO C++ API部署RT-DETR模型

    應(yīng)用中,我們?yōu)榱伺c當前軟件平臺集成更多會采用 C++ 平臺,因此在本文中,我們將基于 OpenVINO C++ API 向大家展示了不包含后處理的 RT-DETR 模型的部署流程,并向大家展示如何導(dǎo)出不包含后處理的 RT-DET
    的頭像 發(fā)表于 11-03 14:30 ?706次閱讀
    基于OpenVINO <b class='flag-5'>C++</b> API部署RT-DETR<b class='flag-5'>模型</b>

    C++之父新作帶你勾勒現(xiàn)代C++地圖

    為了幫助大家解決這些痛點問題,讓大家領(lǐng)略現(xiàn)代C++之美,掌握其中的精髓,更好地使用C++,C++之父Bjarne Stroustrup坐不住了,他親自操刀寫就了這本《C++之旅》!
    的頭像 發(fā)表于 10-30 16:35 ?746次閱讀
    <b class='flag-5'>C++</b>之父新作帶你勾勒現(xiàn)代<b class='flag-5'>C++</b>地圖

    模仿RT_Thread的設(shè)備驅(qū)動模型,使用C++實現(xiàn)

    由于目前本人就職的公司不允許自由使用操作系統(tǒng)開發(fā),且公司一般為C/C++混合開發(fā)的模式,驅(qū)動的開發(fā)也十分的草率,驅(qū)動代碼與應(yīng)用代碼雜糅在一起,十分的不清晰。
    的頭像 發(fā)表于 10-24 14:47 ?798次閱讀
    模仿RT_Thread的設(shè)備驅(qū)動<b class='flag-5'>模型</b>,使用<b class='flag-5'>C++</b><b class='flag-5'>實現(xiàn)</b>