在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

如何在CUDA程序中簡化內(nèi)核和數(shù)據(jù)副本的并發(fā)

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

掃碼添加小助手

加入工程師交流群

異構計算是指高效地使用系統(tǒng)中的所有處理器,包括 CPUGPU 。為此,應用程序必須在多個處理器上并發(fā)執(zhí)行函數(shù)。 CUDA 應用程序通過在 streams 中執(zhí)行異步命令來管理并發(fā)性,這些命令是按順序執(zhí)行的。不同的流可以并發(fā)地執(zhí)行它們的命令,也可以彼此無序地執(zhí)行它們的命令。[見帖子[See the post 如何在 CUDA C / C ++中實現(xiàn)數(shù)據(jù)傳輸?shù)闹丿B ]

在不指定流的情況下執(zhí)行異步 CUDA 命令時,運行時使用默認流。在 CUDA 7 之前,默認流是一個特殊流,它隱式地與設備上的所有其他流同步。

CUDA 7 引入了大量強大的新功能 ,包括一個新的選項,可以為每個主機線程使用獨立的默認流,這避免了傳統(tǒng)默認流的序列化。在這篇文章中,我將向您展示如何在 CUDA 程序中簡化實現(xiàn)內(nèi)核和數(shù)據(jù)副本之間的并發(fā)。

CUDA 中的異步命令

如 CUDA C 編程指南所述,異步命令在設備完成請求的任務之前將控制權返回給調用主機線程(它們是非阻塞的)。這些命令是:

  • 內(nèi)核啟動;
  • 存儲器在兩個地址之間復制到同一設備存儲器;
  • 從主機到設備的 64kb 或更少內(nèi)存塊的內(nèi)存拷貝;
  • 由后綴為 Async 的函數(shù)執(zhí)行的內(nèi)存復制;
  • 內(nèi)存設置函數(shù)調用。

為內(nèi)核啟動或主機設備內(nèi)存復制指定流是可選的;您可以調用 CUDA 命令而不指定流(或通過將 stream 參數(shù)設置為零)。下面兩行代碼都在默認流上啟動內(nèi)核。

  kernel<<< blocks, threads, bytes >>>();    // default stream
  kernel<<< blocks, threads, bytes, 0 >>>(); // stream 0

默認流

在并發(fā)性對性能不重要的情況下,默認流很有用。在 CUDA 7 之前,每個設備都有一個用于所有主機線程的默認流,這會導致隱式同步。正如 CUDA C 編程指南中的“隱式同步”一節(jié)所述,如果主機線程向它們之間的默認流發(fā)出任何 CUDA 命令,來自不同流的兩個命令就不能并發(fā)運行。

CUDA 7 引入了一個新選項, 每線程默認流 ,它有兩個效果。首先,它為每個主機線程提供自己的默認流。這意味著不同主機線程向默認流發(fā)出的命令可以并發(fā)運行。其次,這些默認流是常規(guī)流。這意味著默認流中的命令可以與非默認流中的命令同時運行。

要在 nvcc 7 及更高版本中啟用每線程默認流,您可以在包含 CUDA 頭( cuda.h 或 cuda_runtime.h )之前,使用 nvcc 命令行選項 CUDA 或 #define 編譯 CUDA_API_PER_THREAD_DEFAULT_STREAM 預處理器宏。需要注意的是:當代碼由 nvcc 編譯時,不能使用 #define CUDA_API_PER_THREAD_DEFAULT_STREAM 在。 cu 文件中啟用此行為,因為 nvcc 在翻譯單元的頂部隱式包含了 cuda_runtime.h 。

多流示例

讓我們看一個小例子。下面的代碼簡單地在八個流上啟動一個簡單內(nèi)核的八個副本。我們只為每個網(wǎng)格啟動一個線程塊,這樣就有足夠的資源同時運行多個線程塊。作為遺留默認流如何導致序列化的示例,我們在默認流上添加了不起作用的虛擬內(nèi)核啟動。這是密碼。

const int N = 1 << 20;

__global__ void kernel(float *x, int n)
{
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    for (int i = tid; i < n; i += blockDim.x * gridDim.x) {
        x[i] = sqrt(pow(3.14159,i));
    }
}

int main()
{
    const int num_streams = 8;

    cudaStream_t streams[num_streams];
    float *data[num_streams];

    for (int i = 0; i < num_streams; i++) {
        cudaStreamCreate(&streams[i]);

        cudaMalloc(&data[i], N * sizeof(float));

        // launch one worker kernel per stream
        kernel<<<1, 64, 0, streams[i]>>>(data[i], N);

        // launch a dummy kernel on the default stream
        kernel<<<1, 1>>>(0, 0);
    }

    cudaDeviceReset();

    return 0;
}

首先讓我們檢查遺留行為,通過不帶選項的編譯。

nvcc ./stream_test.cu -o stream_legacy

我們可以在 NVIDIA visualprofiler (nvvp)中運行該程序,以獲得顯示所有流和內(nèi)核啟動的時間軸。圖 1 顯示了 Macbook Pro 上生成的內(nèi)核時間線,該 Macbook Pro 帶有 NVIDIA GeForce GT 750M (一臺開普勒 GPU )。您可以看到默認流上虛擬內(nèi)核的非常小的條,以及它們?nèi)绾螌е滤衅渌餍蛄谢?/p>

現(xiàn)在讓我們嘗試新的每線程默認流。

nvcc --default-stream per-thread ./stream_test.cu -o stream_per-thread

圖 2 顯示了來自nvvp的結果。在這里您可以看到九個流之間的完全并發(fā):默認流(在本例中映射到流 14 )和我們創(chuàng)建的其他八個流。請注意,虛擬內(nèi)核運行得如此之快,以至于很難看到在這個圖像中默認流上有八個調用。

圖 2 :使用新的每線程默認流選項的多流示例,它支持完全并發(fā)執(zhí)行。

多線程示例

讓我們看另一個例子,該示例旨在演示新的默認流行為如何使多線程應用程序更容易實現(xiàn)執(zhí)行并發(fā)。下面的例子創(chuàng)建了八個 POSIX 線程,每個線程在默認流上調用我們的內(nèi)核,然后同步默認流。(我們需要在本例中進行同步,以確保探查器在程序退出之前獲得內(nèi)核開始和結束時間戳。)

#include 
#include 

const int N = 1 << 20;

__global__ void kernel(float *x, int n)
{
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    for (int i = tid; i < n; i += blockDim.x * gridDim.x) {
        x[i] = sqrt(pow(3.14159,i));
    }
}

void *launch_kernel(void *dummy)
{
    float *data;
    cudaMalloc(&data, N * sizeof(float));

    kernel<<<1, 64>>>(data, N);

    cudaStreamSynchronize(0);

    return NULL;
}

int main()
{
    const int num_threads = 8;

    pthread_t threads[num_threads];

    for (int i = 0; i < num_threads; i++) {
        if (pthread_create(&threads[i], NULL, launch_kernel, 0)) {
            fprintf(stderr, "Error creating threadn");
            return 1;
        }
    }

    for (int i = 0; i < num_threads; i++) {
        if(pthread_join(threads[i], NULL)) {
            fprintf(stderr, "Error joining threadn");
            return 2;
        }
    }

    cudaDeviceReset();

    return 0;
}

首先,讓我們編譯時不使用任何選項來測試遺留的默認流行為。

nvcc ./pthread_test.cu -o pthreads_legacy

當我們在nvvp中運行它時,我們看到一個流,默認流,所有內(nèi)核啟動都序列化,如圖 3 所示。

圖 3 :一個具有遺留默認流行為的多線程示例:所有八個線程都被序列化。

讓我們用新的 per-thread default stream 選項編譯它。

nvcc --default-stream per-thread ./pthread_test.cu -o pthreads_per_thread

圖 4 顯示,對于每個線程的默認流,每個線程都會自動創(chuàng)建一個新的流,它們不會同步,因此所有八個線程的內(nèi)核都會并發(fā)運行。

圖 4 :每個線程默認流的多線程示例:所有八個線程的內(nèi)核同時運行。

更多提示

在為并發(fā)進行編程時,還需要記住以下幾點。

記?。簩τ诿烤€程的默認流,每個線程中的默認流的行為與常規(guī)流相同,只要同步和并發(fā)就可以了。對于傳統(tǒng)的默認流,這是不正確的。

--default-stream 選項是按編譯單元應用的,因此請確保將其應用于所有需要它的 nvcc 命令行。

cudaDeviceSynchronize() 繼續(xù)同步設備上的所有內(nèi)容,甚至使用新的每線程默認流選項。如果您只想同步單個流,請使用 cudaStreamSynchronize(cudaStream_t stream) ,如我們的第二個示例所示。

從 CUDA 7 開始,您還可以使用句柄 cudaStreamPerThread 顯式地訪問每線程的默認流,也可以使用句柄 cudaStreamLegacy 訪問舊的默認流。請注意, cudaStreamLegacy 仍然隱式地與每個線程的默認流同步,如果您碰巧在一個程序中混合使用它們。

您可以通過將 cudaStreamCreate() 標志傳遞給 cudaStreamCreate() 來創(chuàng)建不與傳統(tǒng)默認流同步的 非阻塞流 。

關于作者

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

審核編輯:郭婷

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

    關注

    68

    文章

    19868

    瀏覽量

    234505
  • cpu
    cpu
    +關注

    關注

    68

    文章

    11067

    瀏覽量

    216666
  • gpu
    gpu
    +關注

    關注

    28

    文章

    4934

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    何在 樹莓派 上編寫和運行 C 語言程序?

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

    零基礎入門:如何在樹莓派上編寫和運行Python程序

    在這篇文章,我將為你簡要介紹Python程序是什么、Python程序可以用來做什么,以及如何在RaspberryPi上編寫和運行一個簡單的Python
    的頭像 發(fā)表于 03-25 09:27 ?644次閱讀
    零基礎入門:如<b class='flag-5'>何在</b>樹莓派上編寫和運行Python<b class='flag-5'>程序</b>?

    在imx93,如何在flexio引腳模擬spi功能?

    何在 flexio 引腳模擬 spi 功能?我看到了實現(xiàn) I2C 的文檔,但沒有看到 SPI 的文檔。也搜索了內(nèi)核。誰能提供任何文檔或示例來開始仿真 SPI?
    發(fā)表于 03-21 06:59

    何在SonarWiz中導入和處理磁強計數(shù)據(jù)

    本指南將向您介紹如何在 SonarWiz 中導入和處理磁強計數(shù)據(jù)。 我們概述的程序將減少數(shù)據(jù)的晝夜變化和航向變化,消除層回偏移,并生成總場
    的頭像 發(fā)表于 02-17 17:29 ?376次閱讀
    如<b class='flag-5'>何在</b>SonarWiz中導入和處理磁強計<b class='flag-5'>數(shù)據(jù)</b>

    EE-132:使用VisualDSP將C代碼和數(shù)據(jù)模塊放入SHARC存儲器

    電子發(fā)燒友網(wǎng)站提供《EE-132:使用VisualDSP將C代碼和數(shù)據(jù)模塊放入SHARC存儲器.pdf》資料免費下載
    發(fā)表于 01-07 13:55 ?0次下載
    EE-132:使用VisualDSP將C代碼<b class='flag-5'>和數(shù)據(jù)</b>模塊放入SHARC存儲器<b class='flag-5'>中</b>

    VSS在數(shù)據(jù)備份的作用 VSS技術的優(yōu)勢與劣勢

    的一項服務,它允許用戶創(chuàng)建文件和文件系統(tǒng)的快照,即影子副本。這些快照可以用于數(shù)據(jù)備份、恢復和分析,而不需要中斷當前的文件系統(tǒng)操作。 2. VSS在數(shù)據(jù)備份的作用 一致性備份 :VSS
    的頭像 發(fā)表于 12-13 16:03 ?971次閱讀

    linux內(nèi)核通用HID觸摸驅動

    在linux內(nèi)核,為HID觸摸面板實現(xiàn)了一個通用的驅動程序,位于/drivers/hid/hid-multitouch.c文件。hid觸摸驅動是以struct hid_driver
    的頭像 發(fā)表于 10-29 10:55 ?2181次閱讀
    linux<b class='flag-5'>內(nèi)核</b><b class='flag-5'>中</b>通用HID觸摸驅動

    行業(yè)動態(tài) | 英偉達2024年將出貨10億個RISC-V 內(nèi)核

    據(jù)Tomshardware援引@NickBrownHPC的爆料稱,盡管英偉達(NVIDIA)的GPU依賴于其專有的CUDA內(nèi)核,這些內(nèi)核具有其指令集架構并支持各種數(shù)據(jù)格式。但是在本月的
    的頭像 發(fā)表于 10-29 08:07 ?695次閱讀
    行業(yè)動態(tài) | 英偉達2024年將出貨10億個RISC-V <b class='flag-5'>內(nèi)核</b>

    linux驅動程序如何加載進內(nèi)核

    在Linux系統(tǒng),驅動程序內(nèi)核與硬件設備之間的橋梁。它們允許內(nèi)核與硬件設備進行通信,從而實現(xiàn)對硬件設備的控制和管理。 驅動程序的編寫 驅
    的頭像 發(fā)表于 08-30 15:02 ?1053次閱讀

    IB Verbs和NVIDIA DOCA GPUNetIO性能測試

    Async 等技術,能夠創(chuàng)建以 GPU 為中心的應用程序,其中 CUDA 內(nèi)核可以直接與網(wǎng)卡(NIC)通信,從而繞過 CPU 發(fā)送和接收數(shù)據(jù)包,并將 CPU 排除在關鍵路徑之外。
    的頭像 發(fā)表于 08-23 17:03 ?1273次閱讀
    IB Verbs和NVIDIA DOCA GPUNetIO性能測試

    并發(fā)物聯(lián)網(wǎng)云平臺是什么

    并發(fā)物聯(lián)網(wǎng)云平臺是一種能夠處理大量設備同時連接并進行數(shù)據(jù)交換的云計算平臺。這種平臺通常被設計用來應對來自數(shù)以萬計甚至數(shù)十億計的物聯(lián)網(wǎng)設備的并發(fā)請求,保證系統(tǒng)的穩(wěn)定性和響應速度。 首先,從技術層面
    的頭像 發(fā)表于 08-13 13:50 ?528次閱讀

    內(nèi)核程序漏洞介紹

    電子發(fā)燒友網(wǎng)站提供《內(nèi)核程序漏洞介紹.pdf》資料免費下載
    發(fā)表于 08-12 09:38 ?0次下載

    并發(fā)系統(tǒng)的藝術:如何在流量洪峰中游刃有余

    前言 我們常說的三高,高并發(fā)、高可用、高性能,這些技術是構建現(xiàn)代互聯(lián)網(wǎng)應用程序所必需的。對于京東618備戰(zhàn)來說,所有的臺系統(tǒng)服務,無疑都是圍繞著三高來展開的。而對于京東龐大的客戶群體,高并發(fā)
    的頭像 發(fā)表于 08-05 13:43 ?502次閱讀
    高<b class='flag-5'>并發(fā)</b>系統(tǒng)的藝術:如<b class='flag-5'>何在</b>流量洪峰中游刃有余

    打破英偉達CUDA壁壘?AMD顯卡現(xiàn)在也能無縫適配CUDA

    電子發(fā)燒友網(wǎng)報道(文/梁浩斌)一直以來,圍繞CUDA打造的軟件生態(tài),是英偉達在GPU領域最大的護城河,尤其是隨著目前AI領域的發(fā)展加速,市場火爆,英偉達GPU+CUDA的開發(fā)生態(tài)則更加穩(wěn)固,AMD
    的頭像 發(fā)表于 07-19 00:16 ?5860次閱讀

    何在自己的程序啟用AT模塊?

    對 AT 命令做出反應。 你知道如何在你自己的程序啟用AT模塊嗎? 可能嗎? 樂鑫 SDK NONOS SDK API 文檔介紹了 at_custom.h 和 at_init(),但看起來這是為了開發(fā)
    發(fā)表于 07-16 08:25
    主站蜘蛛池模板: 日本免费在线视频 | 国产日韩欧美一区二区 | 直接在线观看的三级网址 | 日韩电影毛片 | 网站黄色在线观看 | 激情五月激情综合网 | 97福利影院 | 国产片翁熄系列乱在线视频 | 欧美网站色 | 夜夜爱成人免费网站 | 免费亚洲视频在线观看 | 六月婷婷网视频在线观看 | 国产普通话一二三道 | 九九热精品在线 | 狠狠色狠狠色狠狠五月ady | 国产午夜久久精品 | 色老久久精品偷偷鲁一区 | 亚洲精品视频免费 | 日本加勒比在线精品视频 | 天天摸天天躁天天添天天爽 | 日本黄色小说视频 | 亚洲欧美圣爱天天综合 | 看片在线观看免费 | 亚洲人成影院在线高清 | 小雪被老外黑人撑破了视频 | 国产网站免费观看 | 亚洲4区| 99久久成人国产精品免费 | 老头天天吃我奶躁我的动图 | 久久久噜久噜久久gif动图 | 开心色xxxx| 色琪琪一本到影院 | 三级网站免费看 | 中文字幕第一区 | 天天躁夜夜 | 日日天天干 | 中文字幕第二区 | 狠狠色96视频 | 黄色在线观看网站 | 欲色网站 | 一级中文字幕乱码免费 |