国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

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

3天內不再提示

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

星星科技指導員 ? 來源:NVIDIA ? 作者:Mark Harris ? 2022-04-11 10:13 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文是 CUDA C 和 C ++的一個系列,它是 CUDA 并行計算平臺的 C / C ++接口。本系列文章假定您熟悉 C 語言編程。我們將針對 Fortran 程序員運行一系列關于 CUDA Fortran 的文章。這兩個系列將介紹 CUDA 平臺上并行計算的基本概念。從這里起,除非我另有說明,我將用“ CUDA C ”作為“ CUDA C 和 C ++”的速記。 CUDA C 本質上是 C / C ++,具有幾個擴展,允許使用并行的多個線程在 GPU 上執行函數。

CUDA 編程模型基礎

在我們跳轉到 CUDA C 代碼之前, CUDA 新手將從 CUDA 編程模型的基本描述和使用的一些術語中受益。

CUDA 編程模型是一個異構模型,其中使用了 CPU 和 GPU 。在 CUDA 中, host 指的是 CPU 及其存儲器, device 是指 GPU 及其存儲器。在主機上運行的代碼可以管理主機和設備上的內存,還可以啟動在設備上執行的函數 kernels 。這些內核由許多 GPU 線程并行執行。

鑒于 CUDA 編程模型的異構性, CUDA C 程序的典型操作序列是:

聲明并分配主機和設備內存。

初始化主機數據。

將數據從主機傳輸到設備。

執行一個或多個內核。

將結果從設備傳輸到主機。

記住這個操作序列,讓我們看一個 CUDA C 示例。

第一個 CUDA C 程序

在最近的一篇文章中,我演示了 薩克斯比的六種方法 ,其中包括一個 CUDA C 版本。 SAXPY 代表“單精度 A * X + Y ”,是并行計算的一個很好的“ hello world ”示例。在這篇文章中,我將剖析 CUDA C SAXPY 的一個更完整的版本,詳細解釋它的作用和原因。完整的 SAXPY 代碼是:

#include 

__global__
void saxpy(int n, float a, float *x, float *y)
{
 int i = blockIdx.x*blockDim.x + threadIdx.x;
 if (i < n) y[i] = a*x[i] + y[i];
}

int main(void)
{
  int N = 1<<20;
  float *x, *y, *d_x, *d_y;
  x = (float*)malloc(N*sizeof(float));
  y = (float*)malloc(N*sizeof(float));

  cudaMalloc(&d_x, N*sizeof(float));?
  cudaMalloc(&d_y, N*sizeof(float));

  for (int i = 0; i < N; i++) {
    x[i] = 1.0f;
    y[i] = 2.0f;
  }

  cudaMemcpy(d_x, x, N*sizeof(float), cudaMemcpyHostToDevice);
  cudaMemcpy(d_y, y, N*sizeof(float), cudaMemcpyHostToDevice);

  // Perform SAXPY on 1M elements
  saxpy<<<(N+255)/256, 256>>>(N, 2.0f, d_x, d_y);

  cudaMemcpy(y, d_y, N*sizeof(float), cudaMemcpyDeviceToHost);

  float maxError = 0.0f;
  for (int i = 0; i < N; i++)
    maxError = max(maxError, abs(y[i]-4.0f));
  printf("Max error: %f
", maxError);

  cudaFree(d_x);
  cudaFree(d_y);
  free(x);
  free(y);
}

函數saxpy是在 GPU 上并行運行的內核,main函數是宿主代碼。讓我們從宿主代碼開始討論這個程序。

主機代碼

main 函數聲明兩對數組。

  float *x, *y, *d_x, *d_y;
  x = (float*)malloc(N*sizeof(float));
  y = (float*)malloc(N*sizeof(float));

  cudaMalloc(&d_x, N*sizeof(float));
  cudaMalloc(&d_y, N*sizeof(float));

指針x和y指向以典型方式使用malloc分配的主機陣列,d_x和d_y數組指向從CUDA運行時API使用cudaMalloc函數分配的設備數組。CUDA中的主機和設備有獨立的內存空間,這兩個空間都可以從主機代碼進行管理(CUDAC內核也可以在支持它的設備上分配設備內存)。

然后,主機代碼初始化主機數組。在這里,我們設置了一個 1 數組,以及一個 2 數組。

  for (int i = 0; i < N; i++) {
    x[i] = 1.0f;
    y[i] = 2.0f;
  }

為了初始化設備數組,我們只需使用cudaMemcpy將數據從xy復制到相應的設備數組d_xd_y,它的工作方式與標準的 Cmemcpy函數一樣,只是它采用了第四個參數,指定了復制的方向。在本例中,我們使用cudaMemcpyHostToDevice指定第一個(目標)參數是設備指針,第二個(源)參數是主機指針。

  cudaMemcpy(d_x, x, N*sizeof(float), cudaMemcpyHostToDevice);
  cudaMemcpy(d_y, y, N*sizeof(float), cudaMemcpyHostToDevice);

在運行內核之后,為了將結果返回到主機,我們使用cudaMemcpycudaMemcpyDeviceToHost,從d_y指向的設備數組復制到y指向的主機數組。

cudaMemcpy(y, d_y, N*sizeof(float), cudaMemcpyDeviceToHost);

啟動內核

cord [EZX13 內核由以下語句啟動:

saxpy<<<(N+255)/256, 256>>>(N, 2.0, d_x, d_y);

三個 V 形符號之間的信息是 執行配置 ,它指示有多少設備線程并行執行內核。在 CUDA 中,軟件中有一個線程層次結構,它模仿線程處理器在 GPU 上的分組方式。在 CUDA 編程模型中,我們談到啟動一個 grid 為 螺紋塊 的內核。執行配置中的第一個參數指定網格中線程塊的數量,第二個參數指定線程塊中的線程數。

線程塊和網格可以通過為這些參數傳遞 dim3 (一個由 CUDA 用 x 、 y 和 z 成員定義的簡單結構)值來生成一維、二維或三維的線程塊和網格,但是對于這個簡單的示例,我們只需要一維,所以我們只傳遞整數。在本例中,我們使用包含 256 個線程的線程塊啟動內核,并使用整數算術來確定處理數組( (N+255)/256 )的所有 N 元素所需的線程塊數。

對于數組中的元素數不能被線程塊大小平均整除的情況,內核代碼必須檢查內存訪問是否越界。

清理

完成后,我們應該釋放所有分配的內存。對于使用 cudaMalloc() 分配的設備內存,只需調用 cudaFree() 。對于主機內存,請像往常一樣使用 free() 。

cudaFree(d_x);
  cudaFree(d_y);
  free(x);
  free(y);

設備代碼

現在我們繼續討論內核代碼。

__global__
void saxpy(int n, float a, float *x, float *y)
{
 int i = blockIdx.x*blockDim.x + threadIdx.x;
 if (i < n) y[i] = a*x[i] + y[i];
}

在 CUDA 中,我們使用 __global__ de __global__ 說明符定義諸如 Clara 這樣的內核。設備代碼中定義的變量不需要指定為設備變量,因為假定它們駐留在設備上。在這種情況下, n 、 a 和 i 變量將由每個線程存儲在寄存器中,指針 x 和 y 必須是指向設備內存地址空間的指針。這確實是真的,因為當我們從宿主代碼啟動內核時,我們將 d_x 和 d_y 傳遞給了內核。但是,前兩個參數 n 和 a 沒有在主機代碼中顯式傳輸到設備。因為函數參數在 C / C ++中是默認通過值傳遞的,所以 CUDA 運行時可以自動處理這些值到設備的傳輸。 CUDA 運行時 API 的這一特性使得在 GPU 上啟動內核變得非常自然和簡單——這幾乎與調用 C 函數一樣。

在我們的 saxpy 內核中只有兩行。如前所述,內核由多個線程并行執行。如果我們希望每個線程處理結果數組的一個元素,那么我們需要一種區分和標識每個線程的方法。 CUDA 定義變量 blockDim 、 blockIdx 和 threadIdx 。這些預定義變量的類型為 dim3 ,類似于主機代碼中的執行配置參數。預定義變量 blockDim 包含在內核啟動的第二個執行配置參數中指定的每個線程塊的維度。預定義變量 threadIdx 和 blockIdx 分別包含線程塊中線程的索引和網格中的線程塊的索引。表達式:

    int i = blockDim.x * blockIdx.x + threadIdx.x

生成用于訪問數組元素的全局索引。我們在這個例子中沒有使用它,但是還有一個 gridDim ,它包含在啟動的第一個執行配置參數中指定的網格維度。

在使用該索引訪問數組元素之前,將根據元素的數量 n 檢查其值,以確保沒有越界內存訪問。如果一個數組中的元素數不能被線程塊大小平均整除,并且結果內核啟動的線程數大于數組大小,則需要進行此檢查。內核的第二行執行 SAXPY 的元素級工作,除了邊界檢查之外,它與 SAXPY 主機實現的內部循環相同。

if (i < n) y[i] = a*x[i] + y[i];

編譯和運行代碼

CUDA C 編譯器 nvcc 是 NVIDIA CUDA 工具箱 的一部分。為了編譯我們的 SAXPY 示例,我們將代碼保存在一個擴展名為。 cu 的文件中,比如說 saxpy.cu 。然后我們可以用 nvcc 編譯它。

nvcc -o saxpy saxpy.cu

然后我們可以運行代碼:

% ./saxpy
Max error: 0.000000

總結與結論

通過對 SAXPY 的一個簡單的 CUDA C 實現的演練,您現在了解了編程 CUDA C 的基本知識。將 C 代碼“移植”到 CUDA C 只需要幾個 C 擴展:設備內核函數的 __global__ de Clara 說明符;啟動內核時使用的執行配置;內置的設備變量 blockDim 、 blockIdx 和 threadIdx 用來識別和區分并行執行內核的 GPU 線程。

異類 CUDA 編程模型的一個優點是,將現有代碼從 C 移植到 CUDA C 可以逐步完成,一次只能移植一個內核。

在本系列的下一篇文章中,我們將研究一些性能度量和度量。

關于作者

Mark Harris 是 NVIDIA 杰出的工程師,致力于 RAPIDS 。 Mark 擁有超過 20 年的 GPUs 軟件開發經驗,從圖形和游戲到基于物理的模擬,到并行算法和高性能計算。當他還是北卡羅來納大學的博士生時,他意識到了一種新生的趨勢,并為此創造了一個名字: GPGPU (圖形處理單元上的通用計算)。

審核編輯:郭婷

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

    關注

    39

    文章

    7738

    瀏覽量

    171650
  • cpu
    cpu
    +關注

    關注

    68

    文章

    11277

    瀏覽量

    224949
  • gpu
    gpu
    +關注

    關注

    28

    文章

    5194

    瀏覽量

    135431
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    C語言與C++的區別及聯系

    C語言和C++到底是什么關系? 首先C++C語言本來就是兩種不同的編程語言,但C++確實是對C
    發表于 12-24 07:23

    CC++之間的聯系

    1、語法兼容性: C++完全兼容C語言的語法,這意味著任何有效的C語言程序都可以直接在C++編譯器下編譯通過。 2、底層控制: C++
    發表于 12-11 06:51

    C語言和C++之間的區別是什么

    區別 1、面向對象編程 (OOP): C語言是一種面向過程的語言,它強調的是通過函數將任務分解為一系列步驟進行執行。 C++C語言的基礎上擴展了面向對象的特性,支持類(class)、封裝、繼承
    發表于 12-11 06:23

    為啥 AI 計算速度這么驚人?—— 聊聊 GPU、內存與并行計算

    提到AI,大家常說它“算得快”,其實是指AI能在眨眼間處理海量數據。可它為啥有這本事?答案就藏在“GPU+高速內存+并行計算”這trio(組合)里。咱們可以把AI要處理的數據,想象成一大堆“小任務
    的頭像 發表于 12-05 14:35 ?848次閱讀
    為啥 AI <b class='flag-5'>計算</b>速度這么驚人?—— 聊聊 GPU、內存與<b class='flag-5'>并行計算</b>

    一文看懂AI大模型的并行訓練方式(DP、PP、TP、EP)

    大家都知道,AI計算(尤其是模型訓練和推理),主要以并行計算為主。AI計算中涉及到的很多具體算法(例如矩陣相乘、卷積、循環層、梯度運算等),都需要基于成千上萬的GPU,以并行任務的方式
    的頭像 發表于 11-28 08:33 ?1848次閱讀
    一文看懂AI大模型的<b class='flag-5'>并行</b>訓練方式(DP、PP、TP、EP)

    C/C++代碼靜態測試工具Perforce QAC 2025.3的新特性

    ?Perforce Validate?中?QAC?項目的相對/根路徑的支持。C++?分析也得到了增強,增加了用于檢測 C++?并發問題的新檢查,并改進了實體名稱和實
    的頭像 發表于 10-13 18:11 ?568次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>代碼靜態測試工具Perforce QAC 2025.3的新特性

    神經網絡的并行計算與加速技術

    問題。因此,并行計算與加速技術在神經網絡研究和應用中變得至關重要,它們能夠顯著提升神經網絡的性能和效率,滿足實際應用中對快速響應和大規模數據處理的需求。神經網絡并行
    的頭像 發表于 09-17 13:31 ?1124次閱讀
    神經網絡的<b class='flag-5'>并行計算</b>與加速技術

    從自然仿真到智能調度——GPU并行計算的多場景突破

    的體系結構,成為科學仿真與智能調度的核心計算平臺。在自然現象模擬中,風沙流、流體力學等問題往往涉及海量粒子間的相互作用,計算負擔極為沉重,而GPU的并行鄰居搜索與空間
    的頭像 發表于 09-03 10:32 ?822次閱讀
    從自然仿真到智能調度——GPU<b class='flag-5'>并行計算</b>的多場景突破

    Kintex UltraScale 純 FPGA 開發平臺,釋放高速并行計算潛能,高性價比的 FPGA 解決方案

    璞致電子PZ-KU060-KFB開發板采用Xilinx Kintex UltraScale KU060芯片,提供高密度并行計算能力,配備4GB DDR4內存、20對GTH高速收發器和多種擴展接口
    的頭像 發表于 08-18 13:28 ?720次閱讀
    Kintex UltraScale 純 FPGA 開發<b class='flag-5'>平臺</b>,釋放高速<b class='flag-5'>并行計算</b>潛能,高性價比的 FPGA 解決方案

    技能+1!如何在樹莓派上使用C++控制GPIO?

    在使用樹莓派時,你會發現Python和Scratch是許多任務(包括GPIO編程)中最常用的編程語言。但你知道嗎,你也可以使用C++進行GPIO編程,而且這樣做還有不少好處。借助WiringPi
    的頭像 發表于 08-06 15:33 ?4150次閱讀
    技能+1!如何在樹莓派上使用<b class='flag-5'>C++</b>控制GPIO?

    請問是否可以在通用Windows平臺中構建OpenVINO? GenAI C++ 應用程序?

    無法在通用 Windows 平臺中構建OpenVINO? GenAI C++ 應用程序
    發表于 06-24 07:35

    邊緣AI廣泛應用推動并行計算崛起及創新GPU滲透率快速提升

    是時候重新教育整個生態了。邊緣AI的未來不屬于那些高度優化但功能狹窄的芯片,而是屬于可編程的、可適配的并行計算平臺,它們能與智能軟件共同成長并擴展。
    的頭像 發表于 06-11 14:57 ?676次閱讀

    主流的 MCU 開發語言為什么是 C 而不是 C++?

    在單片機的地界兒里,C語言穩坐中軍帳,C++想分杯羹?難嘍。咱電子工程師天天跟那針尖大的內存空間較勁,C++那些花里胡哨的玩意兒,在這兒真玩不轉。先說內存這道坎兒。您當stm32f4的256kRAM
    的頭像 發表于 05-21 10:33 ?1037次閱讀
    主流的 MCU 開發語言為什么是 <b class='flag-5'>C</b> 而不是 <b class='flag-5'>C++</b>?

    簡單了解I2C接口

    在電子電路的復雜世界里,各種電路模塊設備需要相互通信才能協同工作 ,I2C接口就像是電路模塊設備間的溝通橋梁,今天就帶大家深入了解它。
    的頭像 發表于 05-08 14:15 ?2514次閱讀
    <b class='flag-5'>簡單</b>了解I2<b class='flag-5'>C</b><b class='flag-5'>接口</b>

    讀懂極易并行計算:定義、挑戰與解決方案

    GPU經常與人工智能同時提及,其中一個重要原因在于AI與3D圖形處理本質上屬于同一類問題——它們都適用極易并行計算。什么是極易并行計算?極易并行計算指的是符合以下特征的計算任務:任務獨
    的頭像 發表于 04-17 09:11 ?818次閱讀
    讀懂極易<b class='flag-5'>并行計算</b>:定義、挑戰與解決方案