Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

CUDA Graph

@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそすべては、SystemC v0.9公開から始まった 

CUDA 10.2 のドキュメントを眺めていた時見つけた、CUDA Graph なるもの。

devblogs.nvidia.com

このブログに詳しく書いてあります。

CUDA Graphは、CUDA 10 にて導入されていたんですが、V100のTensorCoreの機能がビック過ぎて、あまり気にしていなかった。

devblogs.nvidia.com

Kernelと遂次呼び出すと、Kernelの起動等のオーバーヘッドがかかるんだよね。

Kernelの実行時間がそれなりの長さなら相対的に気にすることは無いんだけど、Kernelの実行時間が短くなってくると、Kernelの起動時間ってかなり気になるんだよね。

そこで、Streamを使って、Kernelの起動と実行をオーバーラップさせるんだけど、

 

それを改善するのが CUDA Graph。

カーネルをNodeにして、Graphを作り、そのGraphを繰り返し実行するというもの。

 

これ、昔やっていたものに使えるじゃん。。。まー、みんながそんな悩みを持ち始めたのでNVIDIAもCUDAに入れてきたんだろうね。

それから、Kernelの実行時間が短いものの組み合わせて何回も繰り返すようなものが、ディープラーニングのモデルに出現したからかもしれないね。。。

 

で、CUDA 11 ではこのCUDA Graph にも、L2 Persisting Accesses をサポート。

cudaKernelNodeAttrValue node_attribute; // Kernel level attributes data structure
node_attribute.accessPolicyWindow.base_ptr = reinterpret_cast<void*>(ptr); // Global Memory data pointer
node_attribute.accessPolicyWindow.num_bytes = num_bytes; // Number of bytes for persistence access.
// (Must be less than cudaDeviceProp::accessPolicyMaxWindowSize)
node_attribute.accessPolicyWindow.hitRatio = 0.6; // Hint for cache hit ratio
node_attribute.accessPolicyWindow.hitProp = cudaAccessPropertyPersisting; // Type of access property on cache hit
node_attribute.accessPolicyWindow.missProp = cudaAccessPropertyStreaming; // Type of access property on cache miss.

//Set the attributes to a CUDA Graph Kernel node of type cudaGraphNode_t
cudaGraphKernelNodeSetAttribute(node, cudaKernelNodeAttributeAccessPolicyWindow, &node_attribute);

 小さなKernelがデータをパイプライン的に使う時はまさにこれが必要だよね。

 

もっと早く欲しかった機能ですわ。