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

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

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

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

如何在CUDA C/C++中實(shí)現(xiàn)主機(jī)和設(shè)備同步執(zhí)行

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

掃碼添加小助手

加入工程師交流群

在 本系列文章的第一篇 中,我們通過檢查 CUDA C/C++ SAXPY 來研究 CUDA C / C ++的基本元素。在第二篇文章中,我們將討論如何分析這個(gè)和其他 CUDA C / C ++代碼的性能。我們將依賴于這些性能測量技術(shù)在未來的職位,性能優(yōu)化將變得越來越重要。

CUDA 性能度量通常是從主機(jī)代碼中完成的,可以使用 CPU 計(jì)時(shí)器或 CUDA 特定計(jì)時(shí)器來實(shí)現(xiàn)。在討論這些性能度量技術(shù)之前,我們需要討論如何在主機(jī)和設(shè)備之間同步執(zhí)行。

主機(jī)設(shè)備同步

讓我們看看數(shù)據(jù)傳輸和來自上一篇文章的 SAXPY 主機(jī)代碼的內(nèi)核啟動(dòng):

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

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



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



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

使用cudaMemcpy()在主機(jī)和設(shè)備之間的數(shù)據(jù)傳輸是synchronous(或blocking)傳輸。同步數(shù)據(jù)傳輸在之前發(fā)出的所有 CUDA 調(diào)用完成之前不會(huì)開始,后續(xù)的 CUDA 調(diào)用在同步傳輸完成之前無法開始。因此,第三行的saxpy內(nèi)核啟動(dòng)在第二行從yd_y的傳輸完成后才會(huì)發(fā)出。另一方面,內(nèi)核啟動(dòng)是異步的。一旦內(nèi)核在第三行啟動(dòng),控制權(quán)立即返回到 CPU ,而不是等待內(nèi)核完成。而 MIG ht 似乎為設(shè)備在最后一行主機(jī)數(shù)據(jù)傳輸設(shè)置了一個(gè)競爭條件,數(shù)據(jù)傳輸?shù)淖枞再|(zhì)確保了內(nèi)核在傳輸開始之前完成。

用 CPU 計(jì)時(shí)器計(jì)時(shí)內(nèi)核執(zhí)行

現(xiàn)在讓我們來看看如何使用 CPU 計(jì)時(shí)器為內(nèi)核執(zhí)行計(jì)時(shí)。

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

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



t1 = myCPUTimer();

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

cudaDeviceSynchronize();

t2 = myCPUTimer();



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

除了對(duì)通用主機(jī)時(shí)間戳函數(shù)myCPUTimer()的兩次調(diào)用外,我們還使用顯式同步屏障cudaDeviceSynchronize()來阻止 CPU 的執(zhí)行,直到設(shè)備上以前發(fā)出的所有命令都已完成。如果沒有這個(gè)屏障,這段代碼將測量內(nèi)核發(fā)射時(shí)間,而不是內(nèi)核執(zhí)行時(shí)間

使用 CUDA 事件計(jì)時(shí)

使用主機(jī)設(shè)備同步點(diǎn)(如cudaDeviceSynchronize()的一個(gè)問題是它們會(huì)暫停 GPU 管道。因此, CUDA 通過CUDA 事件 API為 CPU 定時(shí)器提供了一個(gè)相對(duì)輕量級(jí)的替代方案。 CUDA 事件 API 包括在兩個(gè)記錄的事件之間調(diào)用create破壞事件、record事件和以毫秒為單位計(jì)算已用時(shí)間

CUDA 事件利用?CUDA?streams. CUDA 流只是按順序在設(shè)備上執(zhí)行的操作序列。在某些情況下[vx3 . 4 可以交叉使用 vx3 . 4]的流。到目前為止, GPU 上的所有操作都發(fā)生在默認(rèn)流或流 0 (也稱為“空流”)中。

在下面的清單中,我們將 CUDA 事件應(yīng)用于 SAXPY 代碼。

cudaEvent_t start, stop;

cudaEventCreate(&start);

cudaEventCreate(&stop);



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

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



cudaEventRecord(start);

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

cudaEventRecord(stop);



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



cudaEventSynchronize(stop);

float milliseconds = 0;

cudaEventElapsedTime(&milliseconds, start, stop);

CUDA 事件屬于cudaEvent_t類型,使用cudaEventCreate()cudaEventDestroy()創(chuàng)建和銷毀事件。在上面的代碼中cudaEventRecord()將啟動(dòng)和停止事件放入默認(rèn)流 stream 0 。當(dāng)事件到達(dá)流中的事件時(shí),設(shè)備將記錄事件的時(shí)間戳。函數(shù)cudaEventSynchronize()會(huì)阻止 CPU 的執(zhí)行,直到記錄指定的事件為止。cudaEventElapsedTime()函數(shù)在第一個(gè)參數(shù)中返回錄制startstop之間經(jīng)過的毫秒數(shù)。該值的分辨率約為半微秒。

內(nèi)存帶寬

現(xiàn)在我們有了一種精確計(jì)時(shí)內(nèi)核執(zhí)行的方法,我們將使用它來計(jì)算帶寬。在評(píng)估帶寬效率時(shí),我們同時(shí)使用理論峰值帶寬和觀察到的或有效的內(nèi)存帶寬。

理論帶寬

理論帶寬可以使用產(chǎn)品文獻(xiàn)中提供的硬件規(guī)格計(jì)算。例如, NVIDIA Tesla M2050 GPU 使用內(nèi)存時(shí)鐘速率為 1546 MHz 的 DDR (雙數(shù)據(jù)速率) RAM 和 384 位寬的內(nèi)存接口。使用這些數(shù)據(jù)項(xiàng), NVIDIA Tesla M2050 的峰值理論內(nèi)存帶寬為 148 GB / s ,如下所示。

BWTheoretical= 1546 * 106* (384 / 8) * 2 / 109= 148 GB / s

在這個(gè)計(jì)算中,我們將內(nèi)存時(shí)鐘速率轉(zhuǎn)換為赫茲,乘以接口寬度(除以 8 ,將位轉(zhuǎn)換為字節(jié)),再乘以 2 ,這是由于數(shù)據(jù)速率加倍。最后,我們除以 109將結(jié)果轉(zhuǎn)換為 GB / s 。

有效帶寬

我們通過計(jì)時(shí)特定的程序活動(dòng)和了解程序如何訪問數(shù)據(jù)來計(jì)算有效帶寬。我們用下面的等式。

BWEffective=(RB+WB( VZX50]* 109)

這里,BWEffective有效帶寬,單位為 GB / s ,RB是每個(gè)內(nèi)核讀取的字節(jié)數(shù),WB是每個(gè)內(nèi)核寫入的字節(jié)數(shù),t是以秒為單位的運(yùn)行時(shí)間。下面是完整的代碼。

#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 = 20 * (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;

  }



  cudaEvent_t start, stop;

  cudaEventCreate(&start);

  cudaEventCreate(&stop);



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

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



  cudaEventRecord(start);



  // Perform SAXPY on 1M elements

  saxpy<<<(N+511)/512, 512>>>(N, 2.0f, d_x, d_y);



  cudaEventRecord(stop);



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



  cudaEventSynchronize(stop);

  float milliseconds = 0;

  cudaEventElapsedTime(&milliseconds, start, stop);



  float maxError = 0.0f;

  for (int i = 0; i < N; i++) {

    maxError = max(maxError, abs(y[i]-4.0f));

  }



  printf("Max error: %fn", maxError);

  printf("Effective Bandwidth (GB/s): %fn", N*4*3/milliseconds/1e6);

}

在帶寬計(jì)算中,N*4是每個(gè)數(shù)組讀或?qū)憘鬏數(shù)淖止?jié)數(shù), 3 的因子表示x的讀取和y的讀寫。經(jīng)過的時(shí)間存儲(chǔ)在變量milliseconds中,以明確單位。請(qǐng)注意,除了添加帶寬計(jì)算所需的功能外,我們還更改了數(shù)組大小和線程塊大小。在 Tesla M2050 上編譯并運(yùn)行此代碼:

$ ./saxpy

Max error: 0.000000

Effective Bandwidth (GB/s): 110.374872

測量計(jì)算吞吐量

我們剛剛演示了如何測量帶寬,帶寬是數(shù)據(jù)吞吐量的度量。另一個(gè)對(duì)性能非常重要的指標(biāo)是計(jì)算吞吐量。計(jì)算吞吐量的常用度量是 GFLOP / s ,它代表“每秒千兆浮點(diǎn)運(yùn)算”,其中 Giga 是 10 的前綴9. 我們通常測量 SAXPY 的吞吐量,因?yàn)槊恳粋€(gè) SAXPY 運(yùn)算都是有效的

GFLOP/s Effective== 2 N /( t :《* 109)

N 是 SAXPY 操作中的元素?cái)?shù), t 是以秒為單位的運(yùn)行時(shí)間。與理論峰值帶寬一樣,理論峰值 GFLOP / s 可以從產(chǎn)品文獻(xiàn)中獲得(但是計(jì)算它可能有點(diǎn)棘手,因?yàn)樗c體系結(jié)構(gòu)非常相關(guān))。例如, Tesla M2050 GPU 的單精度浮點(diǎn)吞吐量理論峰值為 1030 GFLOP / s ,雙倍精度的理論峰值吞吐量為 515 GFLOP / s 。

SAXPY 為計(jì)算的每個(gè)元素讀取 12 個(gè)字節(jié),但是只執(zhí)行一個(gè)乘法加法指令( 2 個(gè)浮點(diǎn)運(yùn)算),因此很明顯它是帶寬受限的,因此在這種情況下(實(shí)際上在許多情況下),帶寬是衡量和優(yōu)化的最重要的指標(biāo)。在更復(fù)雜的計(jì)算中,在 FLOPs 級(jí)別測量性能可能非常困難。因此,更常見的是使用分析工具來了解計(jì)算吞吐量是否是一個(gè)瓶頸。應(yīng)用程序通常提供特定于問題(而不是特定于體系結(jié)構(gòu))的吞吐量指標(biāo),因此對(duì)用戶更有用。例如,天文 n 體問題的“每秒十億次相互作用”,或分子動(dòng)力學(xué)模擬的“每天納秒”。

總結(jié)

這篇文章描述了如何使用 CUDA 事件 API 為內(nèi)核執(zhí)行計(jì)時(shí)。 CUDA 事件使用 GPU 計(jì)時(shí)器,因此避免了與主機(jī)設(shè)備同步相關(guān)的問題。我們提出了有效帶寬和計(jì)算吞吐量性能指標(biāo),并在 SAXPY 內(nèi)核中實(shí)現(xiàn)了有效帶寬。很大一部分內(nèi)核是內(nèi)存帶寬限制的,因此計(jì)算有效帶寬是性能優(yōu)化的第一步。在以后的文章中,我們將討論如何確定帶寬、指令或延遲是性能的限制因素。

CUDA 事件還可以用于確定主機(jī)和設(shè)備之間的數(shù)據(jù)傳輸速率,方法是在 cudaMemcpy() 調(diào)用的任一側(cè)記錄事件。

如果你在這個(gè)設(shè)備上運(yùn)行一個(gè)關(guān)于內(nèi)存不足的錯(cuò)誤[ZC9],你可能會(huì)得到一個(gè)更小的錯(cuò)誤。實(shí)際上,到目前為止,我們的示例代碼還沒有費(fèi)心檢查運(yùn)行時(shí)錯(cuò)誤。在[VZX337]中,我們將學(xué)習(xí)如何在 CUDA C / C ++中執(zhí)行錯(cuò)誤處理以及如何查詢當(dāng)前設(shè)備以確定它們可用的資源,以便我們可以編寫更健壯的代碼。

關(guān)于作者

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

審核編輯:郭婷

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

    關(guān)注

    28

    文章

    5194

    瀏覽量

    135432
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    2368

    瀏覽量

    66757
  • 計(jì)時(shí)器
    +關(guān)注

    關(guān)注

    1

    文章

    434

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    keil實(shí)現(xiàn)cc++混合編程

    起因項(xiàng)目中使用到一個(gè)開源的模擬IIC的庫,封裝的比較好,但是是使用c++寫的。于是將其移植到自己的項(xiàng)目中,主要有以下三步操作: 在工程選項(xiàng) C/C++中去掉勾選
    發(fā)表于 01-26 08:58

    C語言與C++的區(qū)別及聯(lián)系

    缺點(diǎn):性能比面向過程低。 二、具體語言上的區(qū)別 1、關(guān)鍵字的不同 C語言有32個(gè)關(guān)鍵字;C++有63個(gè)關(guān)鍵字。 2、后綴名不同 C源文件后綴.c
    發(fā)表于 12-24 07:23

    CC++之間的聯(lián)系

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

    C語言和C++之間的區(qū)別是什么

    區(qū)別 1、面向?qū)ο缶幊?(OOP): C語言是一種面向過程的語言,它強(qiáng)調(diào)的是通過函數(shù)將任務(wù)分解為一系列步驟進(jìn)行執(zhí)行C++C語言的基礎(chǔ)上擴(kuò)展了面向?qū)ο蟮奶匦裕С诸?class)
    發(fā)表于 12-11 06:23

    C/C++條件編譯

    條件編譯是一種在編譯時(shí)根據(jù)條件選擇性地包含或排除部分代碼的處理方法。在 C/C++ ,條件編譯使用預(yù)處理指令 #ifdef、#endif、#else 和 #elif 來實(shí)現(xiàn)。常用的條
    發(fā)表于 12-05 06:21

    C++程序異常的處理機(jī)制

    1、什么是異常處理? 有經(jīng)驗(yàn)的朋友應(yīng)該知道,在正常的CC++編程過程難免會(huì)碰到程序不按照原本設(shè)計(jì)運(yùn)行的情況。 最常見的有除法分母為零,數(shù)組越界,內(nèi)存分配失效、打開相應(yīng)文件失敗等等。 一個(gè)程序
    發(fā)表于 12-02 07:12

    C/C++代碼靜態(tài)測試工具Perforce QAC 2025.3的新特性

    ?Perforce Validate??QAC?項(xiàng)目的相對(duì)/根路徑的支持。C++?分析也得到了增強(qiáng),增加了用于檢測 C++?并發(fā)問題的新檢查,并改進(jìn)了實(shí)體名稱和實(shí)
    的頭像 發(fā)表于 10-13 18:11 ?571次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>代碼靜態(tài)測試工具Perforce QAC 2025.3的新特性

    請(qǐng)問如何在 Keil C51 對(duì) SPROM 進(jìn)行編程?

    何在 Keil C51 對(duì) SPROM 進(jìn)行編程?
    發(fā)表于 08-20 06:12

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

    和PiGPIO等庫,C++可用于編程控制樹莓派的GPIO引腳。它提供了更好的性能和控制能力,非常適合對(duì)速度和精度要求較高的硬件項(xiàng)目。在樹莓派社區(qū),關(guān)于“Python
    的頭像 發(fā)表于 08-06 15:33 ?4151次閱讀
    技能+1!如<b class='flag-5'>何在</b>樹莓派上使用<b class='flag-5'>C++</b>控制GPIO?

    Perforce QAC產(chǎn)品簡介:面向C/C++的靜態(tài)代碼分析工具(已通過SO 26262認(rèn)證)

    Perforce QAC專為C/C++開發(fā)者打造,支持多種編碼規(guī)范、功能安全標(biāo)準(zhǔn)(ISO 26262)等,廣泛用于汽車、醫(yī)療、嵌入式開發(fā)領(lǐng)域,可幫助快速識(shí)別關(guān)鍵缺陷、提升代碼質(zhì)量、實(shí)現(xiàn)合規(guī)交付。
    的頭像 發(fā)表于 07-10 15:57 ?1265次閱讀
    Perforce QAC產(chǎn)品簡介:面向<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>的靜態(tài)代碼分析工具(已通過SO 26262認(rèn)證)

    請(qǐng)問如何在C++中使用NPU上的模型緩存?

    無法確定如何在 C++ 的 NPU 上使用模型緩存
    發(fā)表于 06-24 07:25

    主流的 MCU 開發(fā)語言為什么是 C 而不是 C++

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

    何在 樹莓派 上編寫和運(yùn)行 C 語言程序?

    在本教程,我將討論C編程語言是什么,C編程的用途,以及如何在RaspberryPi上編寫和運(yùn)行C程序。本文的目的是為您介紹在Raspber
    的頭像 發(fā)表于 03-25 09:28 ?1155次閱讀
    如<b class='flag-5'>何在</b> 樹莓派 上編寫和運(yùn)行 <b class='flag-5'>C</b> 語言程序?

    C++學(xué)到什么程度可以找工作?

    C++學(xué)到什么程度可以找工作?要使用C++找到工作,特別是作為軟件開發(fā)人員或相關(guān)職位,通常需要掌握以下幾個(gè)方面: 1. **語言基礎(chǔ)**:你需要對(duì)C++的核心概念有扎實(shí)的理解,包括但不限于指針、內(nèi)存
    發(fā)表于 03-13 10:19

    創(chuàng)建了用于OpenVINO?推理的自定義C++和Python代碼,從C++代碼獲得的結(jié)果與Python代碼不同是為什么?

    創(chuàng)建了用于OpenVINO?推理的自定義 C++ 和 Python* 代碼。 在兩個(gè)推理過程中使用相同的圖像和模型。 從 C++ 代碼獲得的結(jié)果與 Python* 代碼不同。
    發(fā)表于 03-06 06:22