日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

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

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

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

CUDA 中的異步命令

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

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

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

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

默認流

在并發(fā)性對性能不重要的情況下,默認流很有用。在 CUDA 7 之前,每個設(shè)備都有一個用于所有主機線程的默認流,這會導(dǎo)致隱式同步。正如 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 預(yù)處理器宏。需要注意的是:當(dāng)代碼由 nvcc 編譯時,不能使用 #define CUDA_API_PER_THREAD_DEFAULT_STREAM 在。 cu 文件中啟用此行為,因為 nvcc 在翻譯單元的頂部隱式包含了 cuda_runtime.h 。

多流示例

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

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

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

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

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

多線程示例

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

#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

當(dāng)我們在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 選項是按編譯單元應(yīng)用的,因此請確保將其應(yīng)用于所有需要它的 nvcc 命令行。

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

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

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

關(guān)于作者

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

審核編輯:郭婷

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

    關(guān)注

    68

    文章

    20344

    瀏覽量

    255372
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11339

    瀏覽量

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

    關(guān)注

    28

    文章

    5292

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

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

    Linux內(nèi)核驅(qū)動開發(fā)的技術(shù)核心精要

    開發(fā)必須理解的技術(shù)要點,供從業(yè)者參考。 一、并發(fā)與同步:多核系統(tǒng)的根基 現(xiàn)代內(nèi)核默認支持SMP(對稱多處理),驅(qū)動代碼可能同時運行在多個CPU核、中斷、軟中斷、搶占路徑上,競態(tài)風(fēng)險無處不在。
    發(fā)表于 03-10 13:56

    Linux系統(tǒng)內(nèi)核參數(shù)調(diào)優(yōu)實戰(zhàn)指南

    Linux 內(nèi)核參數(shù)調(diào)優(yōu)是系統(tǒng)性能優(yōu)化的核心環(huán)節(jié)。隨著云原生架構(gòu)的普及和硬件性能的飛速提升,默認的內(nèi)核參數(shù)配置往往無法充分發(fā)揮系統(tǒng)潛力。在高并發(fā) Web 服務(wù)、大數(shù)據(jù)處理、容器化部署等
    的頭像 發(fā)表于 01-28 14:27 ?774次閱讀

    何在NVIDIA CUDA Tile編寫高性能矩陣乘法

    本博文是系列課程的一部分,旨在幫助開發(fā)者學(xué)習(xí) NVIDIA CUDA Tile 編程,掌握構(gòu)建高性能 GPU 內(nèi)核的方法,并以矩陣乘法作為核心示例。
    的頭像 發(fā)表于 01-22 16:43 ?5343次閱讀
    如<b class='flag-5'>何在</b>NVIDIA <b class='flag-5'>CUDA</b> Tile<b class='flag-5'>中</b>編寫高性能矩陣乘法

    一文說透了如何實現(xiàn)單片機的多任務(wù)并發(fā)!

    在嵌入式系統(tǒng)開發(fā),多任務(wù)并發(fā)是非常常見的,對于處理復(fù)雜的應(yīng)用場景、提升系統(tǒng)的并發(fā)能力、提高系統(tǒng)的實時性等方面都有很大好處。在單片機實現(xiàn)多任務(wù)并發(fā)
    發(fā)表于 01-06 06:46

    NVIDIA CUDA Tile的創(chuàng)新之處、工作原理以及使用方法

    NVIDIA CUDA 13.1 推出 NVIDIA CUDA Tile,這是自 2006 年 NVIDIA CUDA 平臺發(fā)明以來,最大的一次技術(shù)進步。這一令人振奮的創(chuàng)新引入了一套面向
    的頭像 發(fā)表于 12-24 10:17 ?705次閱讀
    NVIDIA <b class='flag-5'>CUDA</b> Tile的創(chuàng)新之處、工作原理以及使用方法

    在Python借助NVIDIA CUDA Tile簡化GPU編程

    NVIDIA CUDA 13.1 版本新增了基于 Tile 的GPU 編程模式。它是自 CUDA 發(fā)明以來 GPU 編程最核心的更新之一。借助 GPU tile kernels,可以用比 SIMT
    的頭像 發(fā)表于 12-13 10:12 ?1487次閱讀
    在Python<b class='flag-5'>中</b>借助NVIDIA <b class='flag-5'>CUDA</b> Tile<b class='flag-5'>簡化</b>GPU編程

    NVIDIA CUDA 13.1版本的新增功能與改進

    NVIDIA CUDA 13.1 是自 CUDA 二十年前發(fā)明以來,規(guī)模最大、內(nèi)容最全面的一次更新。
    的頭像 發(fā)表于 12-13 10:08 ?2496次閱讀

    labview怎么精準的控制副本vi的啟停

    labview的副本vi怎么進行控制,比如我用異步調(diào)用了兩個副本出來,但是我想去讓其中一個vi停止,另一個不變或者達到前一個的相同條件后中止。然后再保證副本vi的名稱不變的情況下讓它又運行起來。
    發(fā)表于 11-02 23:34

    工業(yè)物聯(lián)網(wǎng)數(shù)據(jù)臺的高并發(fā)性有什么作用

    工業(yè)物聯(lián)網(wǎng)數(shù)據(jù)臺的高并發(fā)性是保障其在復(fù)雜工業(yè)場景下穩(wěn)定運行的核心能力之一。它的核心作用是確保大量設(shè)備同時接入和數(shù)據(jù)傳輸時,系統(tǒng)依然能高效處理、不卡頓、不丟失
    的頭像 發(fā)表于 10-28 11:28 ?401次閱讀
    工業(yè)物聯(lián)網(wǎng)<b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>中</b>臺的高<b class='flag-5'>并發(fā)</b>性有什么作用

    何在vivadoHLS中使用.TLite模型

    測試 在Vivado HLS運行綜合、高級綜合和RTL仿真,確保設(shè)計正確。 注意事項 以上步驟是一個簡化的示例,具體的實現(xiàn)可能因您的模型和需求而有所不同。在實際應(yīng)用,您可能需要進一步優(yōu)化接口
    發(fā)表于 10-22 06:29

    如何理解工業(yè)數(shù)據(jù)臺的高并發(fā)能力

    工業(yè)數(shù)據(jù)臺的高并發(fā)能力是指其在同一時間段內(nèi)高效處理大量設(shè)備數(shù)據(jù)讀寫、分析請求的能力,這是保障工業(yè)數(shù)據(jù)實時采集、傳輸、處理與決策響應(yīng)穩(wěn)定性和
    的頭像 發(fā)表于 10-15 11:49 ?453次閱讀

    何在 MA35 系列微處理器 (MPU) 上開發(fā) AMP(非對稱多處理)應(yīng)用程序?

    何在 MA35 系列微處理器 (MPU) 上開發(fā) AMP(非對稱多處理)應(yīng)用程序,并通過建立多個端點的過程促進與其他內(nèi)核的多通道數(shù)據(jù)傳輸。
    發(fā)表于 08-19 06:11

    亞馬遜云科技推出Amazon DocumentDB Serverless,簡化數(shù)據(jù)庫管理并大幅節(jié)省成本

    )的一種全新配置,能夠根據(jù)應(yīng)用程序需求自動擴展計算和內(nèi)存資源。Amazon DocumentDB Serverless簡化數(shù)據(jù)庫管理,無需前期承諾,也不會產(chǎn)生額外成本,與為應(yīng)對峰值負載而長期預(yù)置資源的方式
    的頭像 發(fā)表于 08-15 13:11 ?684次閱讀

    何在下載程序時保護flash的用戶數(shù)據(jù)不被覆蓋?

    使用stm32cubeide或stm32cubeprogrammer燒寫程序,stlink下載器,芯片stm32h743,芯片內(nèi)部flash的0x08100000地址寫有用戶數(shù)據(jù),如何在
    發(fā)表于 08-14 06:38

    何在裸機環(huán)境運行KleidiAI微內(nèi)核

    探索如何在裸機環(huán)境運行 KleidiAI 內(nèi)核,并通過測試多款 C/C++ 編譯器,以確定如何能更高效地生成代碼。
    的頭像 發(fā)表于 08-08 15:16 ?4039次閱讀
    如<b class='flag-5'>何在</b>裸機環(huán)境<b class='flag-5'>中</b>運行KleidiAI微<b class='flag-5'>內(nèi)核</b>
    陕西省| 固始县| 恩平市| 吉安县| 岳西县| 曲阳县| 沛县| 丰台区| 新田县| 同仁县| 鸡泽县| 宜宾县| 浪卡子县| 即墨市| 巴彦淖尔市| 新化县| 修文县| 简阳市| 南川市| 呼玛县| 白沙| 应城市| 西贡区| 崇文区| 镇雄县| 竹山县| 九龙坡区| 耿马| 托里县| 咸丰县| 区。| 安徽省| 灵山县| 泸定县| 黑河市| 安图县| 绥棱县| 温州市| 澄城县| 新营市| 高密市|