CUDAプログラムを実行するときにCPUとGPUメモリの間でデータがどのようにコピーされるのか疑問に思います。具体的には、このプロセスにLinuxカーネルがどのように関与しているかを知りたいです。
いくつかの可能な仮定があります。
- CUDAユーザーライブラリはGPUをファイルとして扱い、
read(2)
各write(2)
トランザクションの合計を呼び出します。 - CUDAユーザーライブラリでは、Linuxは
mmap(2)
関連する制御レジスタ(DMAレジスタ、PIOレジスタ、およびその他のMMIOレジスタ)をユーザースペースに入れてから、ユーザーモードでGPUでランダムな操作を実行する必要があります。 - 他にはありませんか?
strace(1)
私はデータを1000回前後にコピーし、その間に空のカーネルを実行する単純なCUDAプログラムを実行して仮説1を削除しました。ここでwrite(2)
。read(2)
time(1)
仮説#2は、送信されたデータの量がuser
時間ではなく時間によって異なることが観察されたため、可能なようですsys
。したがって、プログラムはユーザーモードでデータをコピーするようです。
ところで少し変なようです。ユーザープログラムがそのような重要なI / O制御レジスタを自分で動作させる方法は何ですか?
このトピックに関する専門的なコメントを聞きたいです。
答え1
アプリケーションは起動時にカーネルからmmap
バッファセットを要求し、このマップを作成するのは特権アクションです。
通常の操作は、単純にこれらのバッファをデータ(テクスチャ、頂点、またはコマンドなど)で埋め、最後に単一のカーネル呼び出しを実行して送信されたコマンドキューを開始します。この起動ストローブは実行される唯一のレジスタアクセスであり、他のすべては共有メモリです。
GPUには、必要な場合を除き、コマンドが他のコンテキストに属するデータを参照できないように独自のデフォルトMMUがあります(たとえば、ゲームのレンダリングターゲットをオーバーレイのレンダリングターゲットと組み合わせて結果をローカルに書き込むシンセサイザなど)画面バッファ)。
コンピューティング専用ワークロードの場合、同じメカニズムがうまく機能します。コマンドキューは、「データを画面に送信」で終わらず、「ホストとしてデータを返す」で終わります。