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

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

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

構(gòu)造具有動(dòng)態(tài)參數(shù)的CUDA圖表

星星科技指導(dǎo)員 ? 來(lái)源:NVIDIA ? 作者:Tu Jiqun ? 2022-10-11 09:43 ? 次閱讀

自從CUDA Graphs在CUDA 10中引入以來(lái),CUDA Graph已經(jīng)用于各種應(yīng)用中。圖形將一組CUDA內(nèi)核和其他CUDA操作組合在一起,并使用指定的依賴關(guān)系樹(shù)執(zhí)行它們。它通過(guò)結(jié)合與CUDA內(nèi)核啟動(dòng)和CUDA API調(diào)用相關(guān)的驅(qū)動(dòng)程序活動(dòng)來(lái)加快工作流。它還通過(guò)硬件加速?gòu)?qiáng)制實(shí)施依賴關(guān)系,而不是在可能的情況下僅依賴CUDA流和事件。

構(gòu)造CUDA圖有兩種主要方法:顯式API調(diào)用和流捕獲。

使用顯式API調(diào)用構(gòu)造CUDA圖

通過(guò)這種構(gòu)建CUDA圖的方法,由CUDA內(nèi)核和CUDA內(nèi)存操作形成的圖節(jié)點(diǎn)通過(guò)調(diào)用cudaGraphAdd*節(jié)點(diǎn)API添加到圖中,其中*被替換為節(jié)點(diǎn)類型。節(jié)點(diǎn)之間的依賴關(guān)系是用API顯式設(shè)置的。

使用顯式API構(gòu)建CUDA圖的好處是,cudaGraphAdd*Node API返回節(jié)點(diǎn)句柄(cudaGraph Node_t),可以用作未來(lái)節(jié)點(diǎn)更新的引用。例如,可以使用cudaGraphExecKernelNodeSetParams以最低成本更新實(shí)例化圖中內(nèi)核節(jié)點(diǎn)的內(nèi)核啟動(dòng)配置和內(nèi)核函數(shù)參數(shù)。

缺點(diǎn)是,在使用CUDA圖加速現(xiàn)有代碼的場(chǎng)景中,使用顯式API調(diào)用構(gòu)造CUDA圖通常需要大量代碼更改,尤其是有關(guān)代碼的控制流和函數(shù)調(diào)用結(jié)構(gòu)的更改。

使用流捕獲構(gòu)建CUDA圖

通過(guò)這種構(gòu)建CUDA圖的方法,cudaStreamBeginCapture和cudaStream EndCapture被放置在代碼塊的前后。代碼塊啟動(dòng)的所有設(shè)備活動(dòng)都會(huì)被記錄、捕獲并分組到CUDA圖中。節(jié)點(diǎn)之間的依賴關(guān)系是從流捕獲區(qū)域內(nèi)的CUDA流或事件API調(diào)用中推斷出來(lái)的。

使用流捕獲構(gòu)建CUDA圖的好處是,對(duì)于現(xiàn)有代碼,需要的代碼更改更少。原始代碼結(jié)構(gòu)可以基本保持不變,圖形構(gòu)造是以自動(dòng)方式執(zhí)行的。

這種構(gòu)建CUDA圖的方法也有缺點(diǎn)。在流捕獲區(qū)域內(nèi),所有內(nèi)核啟動(dòng)配置和內(nèi)核函數(shù)參數(shù)以及CUDA API調(diào)用參數(shù)都按值記錄。每當(dāng)任何配置和參數(shù)發(fā)生更改時(shí),捕獲的然后實(shí)例化的圖形就會(huì)過(guò)期。

在《在動(dòng)態(tài)環(huán)境中使用CUDA圖》一文中提供了兩種解決方案:

重新捕獲工作流。當(dāng)重新捕獲的圖與實(shí)例化的圖具有相同的節(jié)點(diǎn)拓?fù)鋾r(shí),不需要重新實(shí)例化,并且可以使用cudaGraphExecUpdate執(zhí)行整個(gè)圖更新。

以配置和參數(shù)集作為鍵緩存CUDA圖。每組配置和參數(shù)都與緩存中的不同CUDA圖相關(guān)聯(lián)。在運(yùn)行工作流時(shí),配置和參數(shù)集首先被抽象為一個(gè)鍵。然后在緩存中找到相應(yīng)的圖(如果它已經(jīng)存在)并啟動(dòng)。

然而,在某些工作流中,兩種解決方案都不能很好地工作。重新捕獲然后更新方法在紙面上很有效,但在某些情況下,重新捕獲和更新本身的成本很高。也有一些情況下,無(wú)法將每組參數(shù)與CUDA圖相關(guān)聯(lián)。例如,具有浮點(diǎn)數(shù)字參數(shù)的情況很難緩存,因?yàn)榭赡艽嬖诖罅康母↑c(diǎn)數(shù)字。

用顯式API構(gòu)造的CUDA圖很容易更新,但這種方法可能過(guò)于繁瑣,靈活性較差。CUDA圖可以通過(guò)流捕獲靈活地構(gòu)造,但生成的圖很難更新,而且更新成本很高。

綜合方法

在本文中,我提供了一種使用顯式API和流捕獲方法構(gòu)建CUDA圖的方法,從而實(shí)現(xiàn)兩者的優(yōu)點(diǎn),避免兩者的缺點(diǎn)。

例如,在順序啟動(dòng)三個(gè)內(nèi)核的工作流中,前兩個(gè)內(nèi)核具有靜態(tài)啟動(dòng)配置和參數(shù),而最后一個(gè)內(nèi)核具有動(dòng)態(tài)啟動(dòng)配置和屬性。

使用流捕獲來(lái)記錄前兩個(gè)內(nèi)核的啟動(dòng),并調(diào)用顯式API將最后一個(gè)內(nèi)核節(jié)點(diǎn)添加到捕獲圖中。然后,顯式API返回的節(jié)點(diǎn)句柄用于在每次啟動(dòng)圖之前用動(dòng)態(tài)配置和參數(shù)更新實(shí)例化圖。

下面的代碼示例說(shuō)明了這個(gè)想法:

cudaStream_t stream;
std::vector _node_list;
cudaGraphExec_t _graph_exec;

if (not using_graph) {
  
  first_static_kernel<<<1, 1, 0, stream>>>(static_parameters);
  second_static_kernel<<<1, 1, 0, stream>>>(static_parameters);
  dynamic_kernel<<<1, 1, 0, stream>>>(dynamic_parameters);

} else {

  if (capturing_graph) {

    cudaStreamBeginCapture(stream, cudaStreamCaptureModeGlobal);

    first_static_kernel<<<1, 1, 0, stream>>>(static_parameters);
    second_static_kernel<<<1, 1, 0, stream>>>(static_parameters);

    // Get the current stream capturing graph
    cudaGraph_t _capturing_graph;
    cudaStreamCaptureStatus _capture_status;
    const cudaGraphNode_t *_deps;
    size_t _dep_count;
    cudaStreamGetCaptureInfo_v2(stream, &_capture_status, nullptr &_capturing_graph, &_deps, &_dep_count);

    // Manually add a new kernel node
    cudaGraphNode_t new_node;
    cudakernelNodeParams _dynamic_params_cuda;
    cudaGraphAddKernelNode(&new_node, _capturing_graph, _deps, _dep_count, &_dynamic_params_cuda);
    // ... and store the new node for future references
    _node_list.push_back(new_node);

    // Update the stream dependencies
    cudaStreamUpdateCaptureDependencies(stream, &new_node, 1, 1); 

    // End the capture and instantiate the graph
    cudaGraph_t _captured_graph;
    cudaStreamEndCapture(stream, &_captured_graph);

    cudaGraphInstantiate(&_graph_exec, _captured_graph, nullptr, nullptr, 0);

  } else if (updating_graph) {
    cudakernelNodeParams _dynamic_params_updated_cuda;
  
    cudaGraphExecKernelNodeSetParams(_graph_exec, _node_list[0], &_dynamic_params_updated_cuda);

  }
}

在此示例中,cudaStreamGetCaptureInfo_v2提取當(dāng)前正在記錄并捕獲到的CUDA圖形。在調(diào)用cudaStreamUpdateCaptureDependencies更新當(dāng)前捕獲流的依賴項(xiàng)樹(shù)之前,會(huì)將一個(gè)內(nèi)核節(jié)點(diǎn)添加到此圖中,并返回和存儲(chǔ)節(jié)點(diǎn)句柄(new_node)。最后一步是必要的,以確保隨后捕獲的任何其他活動(dòng)都在這些手動(dòng)添加的節(jié)點(diǎn)上正確設(shè)置了它們的依賴項(xiàng)。

使用這種方法,即使參數(shù)是動(dòng)態(tài)的,也可以通過(guò)輕量級(jí)的cudaGraphExecKernelNodeSetParams調(diào)用直接重用相同的實(shí)例化圖(cudaGraph Exec_t對(duì)象)。本文中的第一張圖片顯示了這種用法。

此外,捕獲和更新代碼路徑可以組合成一段代碼,與啟動(dòng)最后兩個(gè)內(nèi)核的原始代碼相鄰。這會(huì)造成最少的代碼更改,并且不會(huì)破壞原始的控制流和函數(shù)調(diào)用結(jié)構(gòu)。

新方法在帶有動(dòng)態(tài)參數(shù)的蜂樹(shù)/cuda圖獨(dú)立代碼示例中詳細(xì)顯示。cudaStreamGetCaptureInfo_v2和cudaStream UpdateCaptureDependencies是CUDA 11.3中引入的新CUDA運(yùn)行時(shí)API。

績(jī)效結(jié)果

使用帶有動(dòng)態(tài)參數(shù)的蜂巢樹(shù)/cuda圖獨(dú)立代碼示例,我用三種不同的方法測(cè)量了運(yùn)行受內(nèi)核啟動(dòng)開(kāi)銷約束的相同動(dòng)態(tài)工作流的性能:

在沒(méi)有CUDA圖形加速的情況下運(yùn)行

使用重新捕獲然后更新方法運(yùn)行CUDA圖

使用本文介紹的組合方法運(yùn)行CUDA圖

表1顯示了結(jié)果。本文中提到的方法的提速很大程度上取決于底層工作流。

結(jié)論

在本文中,我介紹了一種結(jié)合顯式API和流捕獲方法構(gòu)建CUDA圖的方法。它提供了一種以最低成本為具有動(dòng)態(tài)參數(shù)的工作流重用實(shí)例化圖的方法。

關(guān)于作者

Tu Jiqun在加入NVIDIA擔(dān)任高級(jí)計(jì)算機(jī)開(kāi)發(fā)技術(shù)工程師之前,曾獲得哥倫比亞大學(xué)晶格QCD物理學(xué)博士學(xué)位。在NVIDIA,他致力于在最新的NVIDIAGPU上使用最新的硬件和軟件功能,以加速?gòu)V泛的HPC應(yīng)用程序。

審核編輯:郭婷

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

    關(guān)注

    14

    文章

    4862

    瀏覽量

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

    關(guān)注

    2

    文章

    1475

    瀏覽量

    61760
  • CUDA
    +關(guān)注

    關(guān)注

    0

    文章

    121

    瀏覽量

    13587
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    動(dòng)態(tài)環(huán)境中使用CUDA圖提高實(shí)際應(yīng)用程序性能

    具有許多小 CUDA 內(nèi)核的應(yīng)用程序通??梢允褂?CUDA 圖進(jìn)行加速,即使內(nèi)核啟動(dòng)模式在整個(gè)應(yīng)用程序中發(fā)生變化。鑒于這種動(dòng)態(tài)環(huán)境,最佳方法取決于應(yīng)用程序的具體情況。希望您能發(fā)現(xiàn)本文中
    的頭像 發(fā)表于 04-01 16:39 ?3696次閱讀
    在<b class='flag-5'>動(dòng)態(tài)</b>環(huán)境中使用<b class='flag-5'>CUDA</b>圖提高實(shí)際應(yīng)用程序性能

    轎車參數(shù)化分析模型的構(gòu)造研究及應(yīng)用

    轎車參數(shù)化分析模型的構(gòu)造研究及應(yīng)用概念設(shè)計(jì)階段是車身結(jié)構(gòu)設(shè)計(jì)中保證性能的重要階段這個(gè)階段留下的缺陷往往很難在后續(xù)的設(shè)計(jì)中彌補(bǔ)因而在車身開(kāi)發(fā)中受到廣泛重視目前國(guó)內(nèi)外在這方面都展開(kāi)了詳細(xì)的研究尤其是國(guó)外
    發(fā)表于 04-16 13:40

    CUDA/OpenCL支持

    是否有關(guān)于GRID vGPU的CUDA / OpenCL支持的更新信息?以上來(lái)自于谷歌翻譯以下為原文Is there any updated information about CUDA/OpenCL support for GRID vGPU ?
    發(fā)表于 09-07 16:42

    Grid K2 cuda下載位置是?

    我們有一個(gè)使用Grid K2機(jī)器的系統(tǒng)。我試圖在一個(gè)vm的側(cè)面設(shè)置cuda。當(dāng)我使用驅(qū)動(dòng)程序下載頁(yè)面時(shí),它指向NVIDIA-Linux-x86_64-367.57版本的驅(qū)動(dòng)程序似乎工作(它們安裝
    發(fā)表于 10-10 17:02

    CUDA編程教程

    Nvidia CUDA 2.0編程教程
    發(fā)表于 03-05 07:30

    安裝cuda-9.0的過(guò)程

    [cuda] Linux系統(tǒng)多版本cuda環(huán)境下的cuda-90安裝
    發(fā)表于 06-19 17:04

    LInux安裝cuda sdk

    1.安裝toolkit(1)cd /home/CUDA_train/software/cuda4.1(2)./cudatoolkit_4.1.28_linux_64_rhel6.x.run
    發(fā)表于 07-24 06:11

    CUDA教程之Linux系統(tǒng)下CUDA安裝教程

    CUDA教程之1:Linux系統(tǒng)下CUDA安裝教程
    發(fā)表于 06-02 16:53

    什么是CUDA?

    在大家開(kāi)始深度學(xué)習(xí)時(shí),幾乎所有的入門教程都會(huì)提到CUDA這個(gè)詞。那么什么是CUDA?她和我們進(jìn)行深度學(xué)習(xí)的環(huán)境部署等有什么關(guān)系?通過(guò)查閱資料,我整理了這份簡(jiǎn)潔版CUDA入門文檔,希望能幫助大家用最快
    發(fā)表于 07-26 06:28

    什么是CUDA?

    什么是CUDA?
    發(fā)表于 09-28 07:37

    cuda程序設(shè)計(jì)

      •GPGPU及CUDA介紹   •CUDA編程模型   •多線程及存儲(chǔ)器硬件
    發(fā)表于 11-12 16:12 ?0次下載

    帶形狀參數(shù)的曲線曲面的構(gòu)造

    為了更加方便地表示和修改曲線曲面,提出了帶形狀參數(shù)的四次三角Bezier曲線曲面QTBezier的構(gòu)造方法和應(yīng)用。首先仿照Bezier曲線性質(zhì),構(gòu)造了帶形狀參數(shù)的基函數(shù),定義了帶形狀
    發(fā)表于 12-05 18:09 ?0次下載

    基于車輛動(dòng)態(tài)信息的路由構(gòu)造及篩選策略

    引入車輛動(dòng)態(tài)參數(shù)作為構(gòu)造依據(jù)并結(jié)合鏈路有效時(shí)間( LET. link expiration time)進(jìn)行路徑篩選,提高了轉(zhuǎn)發(fā)路徑的穩(wěn)定性及可靠性;仿真表
    發(fā)表于 01-21 11:13 ?0次下載
    基于車輛<b class='flag-5'>動(dòng)態(tài)</b>信息的路由<b class='flag-5'>構(gòu)造</b>及篩選策略

    CUDA簡(jiǎn)介: CUDA編程模型概述

    CUDA 編程模型中,線程是進(jìn)行計(jì)算或內(nèi)存操作的最低抽象級(jí)別。 從基于 NVIDIA Ampere GPU 架構(gòu)的設(shè)備開(kāi)始,CUDA 編程模型通過(guò)異步編程模型為內(nèi)存操作提供加速。 異步編程模型定義了與 CUDA 線程相關(guān)的異
    的頭像 發(fā)表于 04-20 17:16 ?2949次閱讀
    <b class='flag-5'>CUDA</b>簡(jiǎn)介: <b class='flag-5'>CUDA</b>編程模型概述

    支持動(dòng)態(tài)并行的CUDA擴(kuò)展功能和最佳應(yīng)用實(shí)踐

      本文檔描述了支持動(dòng)態(tài)并行的 CUDA 的擴(kuò)展功能,包括為利用這些功能而對(duì) CUDA 編程模型進(jìn)行必要的修改和添加,以及利用此附加功能的指南和最佳實(shí)踐。
    的頭像 發(fā)表于 04-28 09:31 ?1208次閱讀
    支持<b class='flag-5'>動(dòng)態(tài)</b>并行的<b class='flag-5'>CUDA</b>擴(kuò)展功能和最佳應(yīng)用實(shí)踐