web-dev-qa-db-ja.com

CUDACおよびC ++の説明

CUDACとC++の性質について誰かが私に良い説明をすることができますか?私が理解しているように、CUDAはNVIDIAのGPUライブラリを備えたCであると想定されています。現在のところ、CUDACは一部のC++機能をサポートしていますが、他の機能はサポートしていません。

NVIDIAの計画は何ですか?彼らはCに基づいて構築し、C++のライブラリと同等の独自のライブラリ(ThrustとSTLなど)を追加しますか?最終的にはすべてのC++をサポートする予定ですか? .cuファイルでC++ヘッダーを使用するのは悪いことですか?

23
Tianxiang Xiong

CUDA Cは、C構文を使用したプログラミング言語です。概念的には、Cとはかなり異なります。

それが解決しようとしている問題は、複数のプロセッサ用に複数の(類似した)命令スチームをコーディングすることです。

CUDAは、単一命令複数データ(SIMD)ベクトル処理以上のものを提供しますが、データストリーム>>命令ストリーム、またははるかに少ない利点があります。

CUDAはそれを行うためのいくつかのメカニズムを提供し、複雑さのいくつかを隠します。

CUDAは、マルチコアx86のような複数の多様な命令ストリーム用に最適化されていません。 CUDAは、x86ベクトル命令のような単一の命令ストリーム、またはx86ベクトル命令のような特定のデータ型に限定されません。

CUDAは、並行して実行できる「ループ」をサポートしています。これが最も重要な機能です。 CUDAシステムは、「ループ」の実行を分割し、「ループ」本体を同一のプロセッサーの配列全体で同時に実行しますが、通常の順次ループのような錯覚を提供します(具体的には、CUDAはループの「インデックス」を管理します)。開発者は、「ループ」を効果的に作成するためにGPUマシン構造を認識する必要がありますが、ほとんどすべての管理はCUDAランタイムによって処理されます。その効果は、1つの「ループ」と同時に数百(または数千)の「ループ」が完了することです。

CUDAはifブランチのように見えるものをサポートします。 ifテストに一致するコードを実行しているプロセッサのみをアクティブにできるため、プロセッサのサブセットがifテストの「ブランチ」ごとにアクティブになります。例として、これはif... else if ... else ...、3つのブランチがあります。各プロセッサは1つのブランチのみを実行し、ifが完了すると、残りのプロセッサと一緒に移動できるように「再同期」されます。一部の分岐条件がどのプロセッサとも一致しない可能性があります。したがって、そのブランチを実行する必要はありません(たとえば、3つのブランチが最悪の場合です)。次に、1つまたは2つのブランチのみが順番に実行され、if全体がより迅速に完了します。

「魔法」はありません。プログラマーは、コードがCUDAデバイスで実行されることを認識し、そのために意識的にコードを作成する必要があります。

CUDAは古いC/C++コードを使用せず、auto-magicallyプロセッサの配列全体で計算を実行します。 CUDAは、通常のCと多くのC++を順次コンパイルして実行できますが、順次実行され、最新のCPUよりも低速であるため、それによって得られるものはほとんどありません(何もありませんか?)。これは、一部のライブラリのコードが(まだ)CUDA機能とよく一致していないことを意味します。 CUDAプログラムは、マルチキロバイトのビットベクトルを同時に操作できます。 CUDAは、既存のシーケンシャルC/C++ライブラリコードをauto-magically変換できるものに変換することはできません。

CUDAは、使い慣れたC/C++構文を使用してコードを記述する比較的簡単な方法を提供し、いくつかの概念を追加し、プロセッサーの配列全体で実行されるコードを生成します。それは、例えば、10倍以上のスピードアップを与える可能性があります。マルチコアx86。

編集-計画:私はNVIDIAで働いていません

最高のパフォーマンスを得るために、CUDAはコンパイル時に情報を必要とします。

したがって、テンプレートメカニズムは、CUDAコンパイラが使用できるコンパイル時に開発者が物事を言う方法を提供するため、最も便利です。簡単な例として、コンパイル時にマトリックスが2Dおよび4 x 8として定義(インスタンス化)されている場合、CUDAコンパイラーはそれと連携してプロセッサー間でプログラムを編成できます。そのサイズが動的であり、プログラムの実行中に変化する場合、コンパイラまたはランタイムシステムが非常に効率的なジョブを実行するのははるかに困難です

編集:CUDAにはクラスと関数のテンプレートがあります。 CUDAはそうではないと言ってこれを読んだ人がいたらお詫びします。私ははっきりしていなかったことに同意します。

テンプレートのCUDAGPU側の実装は完全ではないと思います。 C++。

ユーザーのハリズムは、私の答えは誤解を招くとコメントしています。ハリズムはNVIDIAで機能するので、アドバイスを待ちます。うまくいけば、これはすでに明確になっています。

複数のプロセッサ間で効率的に実行するのが最も難しいのは、コードを効果的にシリアル化するため、多くの代替パスを動的に分岐することです。最悪の場合、一度に実行できるプロセッサは1つだけであり、GPUの利点が無駄になります。したがって、仮想関数をうまく実行するのは非常に難しいようです。

開発者が理解できるよりもはるかに多くの型情報を推測できる、非常にスマートなプログラム全体の分析ツールがいくつかあります。既存のツールは、仮想関数を排除するのに十分な推論を行う可能性があるため、分岐の分析をコンパイル時間に移します。より良い分岐決定に到達する可能性のあるプログラムの再コンパイルに直接フィードバックする、プログラム実行を計測するための手法もあります。

AFAIK(モジュロフィードバック)CUDAコンパイラは、これらの分野ではまだ最先端ではありません。

(私見では、CUDAまたはOpenCL対応システムを使用している興味のある人は、それらを調査していくつかの実験を行う価値があります。また、これらの分野に興味のある人にとっては、実験する価値があると思います。 Haskell、そして見てください Data Parallel Haskell

20
gbulmer

CUDAは、単一のプログラミング言語ではなく、プラットフォーム(アーキテクチャ、プログラミングモデル、アセンブリ仮想マシン、コンパイルツールなど)です。 CUDA Cは、このプラットフォーム上に構築された多数の言語システムの1つにすぎません(CUDA C、C++、CUDA Fortran、PyCUDAなど)。

CUDA C++

現在、CUDA C++は、 CUDA Cプログラミングガイド の付録D(「C/C++言語サポート」)で説明されているC++のサブセットをサポートしています。

いくつか例を挙げると:

  • クラス
  • __device__メンバー関数(コンストラクタとデストラクタを含む)
  • 継承/派生クラス
  • 仮想関数
  • クラスと関数のテンプレート
  • 演算子とオーバーロード
  • ファンクタークラス

編集:CUDA 7.0以降、CUDA C++には、auto、ラムダ式、範囲など、__device__コード(GPUで実行されるコード)のC++ 11標準のほとんどの言語機能のサポートが含まれています。 -forループ、初期化リスト、静的アサートなどに基づいています。

例と特定の制限についても、上記のリンク先の同じ付録に詳しく説明されています。 CUDAでのC++の使用法の非常に成熟した例として、 推力 をチェックすることをお勧めします。

今後の計画

(開示:私はNVIDIAで働いています。)

将来のリリースとタイミングについて明確にすることはできませんが、CUDAのほぼすべてのリリースで、CUDA C++サポートを現在の(私の意見では非常に便利な)状態にするための言語機能が追加されている傾向を説明できます。 C++のサポートを改善するためにこの傾向を継続する予定ですが、当然、超並列計算アーキテクチャ(GPU)で有用でパフォーマンスの高い機能を優先します。

21
harrism

多くの人には理解されていませんが、CUDAは実際には2つの新しいプログラミング言語であり、どちらもC++から派生しています。 1つは、GPUで実行され、C++のサブセットであるコードを作成するためのものです。その機能はHLSL(DirectX)またはCg(OpenGL)に似ていますが、より多くの機能とC++との互換性があります。さまざまなGPGPU/SIMT /パフォーマンス関連の懸念がそれに当てはまりますが、私は言及する必要はありません。もう1つは、いわゆる「ランタイムAPI」であり、従来の意味ではほとんど「API」ではありません。ランタイムAPIは、ホストCPUで実行されるコードを記述するために使用されます。これはC++のスーパーセットであり、GPUコードへのリンクと起動がはるかに簡単になります。プラットフォームのC++コンパイラを呼び出すNVCCプリコンパイラが必要です。対照的に、Driver API(およびOpenCL)は純粋な標準Cライブラリであり、使用するのがはるかに冗長です(ただし、追加機能はほとんどありません)。

新しいホスト側プログラミング言語の作成は、NVIDIA側の大胆な動きでした。これにより、CUDAの使用をより簡単に開始し、コードをよりエレガントに記述できます。しかし、本当に素晴らしいのは、それを新しい言語として販売することではありませんでした。

6

CUDAはCとC++になると聞くこともありますが、これが不可能であるという単純な理由から、そうではないと思います。彼らのプログラミングガイドから引用するには:

ホストコードの場合、nvccは、ホストc ++コンパイラがサポートするC++ ISO/IEC 14882:2003仕様のすべての部分をサポートします。

デバイスコードの場合、nvccはセクションD.1に示されている機能をサポートしますが、セクションD.2に記載されているいくつかの制限があります。実行時型情報(RTTI)、例外処理、およびC++標準ライブラリはサポートされていません。

私が見ることができるように、それはC++のみを参照し、これがたまたまCとC++の交差点にあるCのみをサポートします。したがって、Cではなくデバイス部分の拡張機能を備えたC++と考えてください。これにより、Cに慣れている場合に多くの頭痛の種を回避できます。

2
Jens Gustedt

NVIDIAの計画は何ですか?

一般的な傾向として、CUDAとOpenCLは、多くのアプリケーションにとって低レベルの手法と見なされていると思います。現在、Nvidiaは OpenACC に多額の投資を行っています。これは、GPU用のOpenMPとして大まかに説明できます。これは宣言型アプローチに従い、GPU並列化の問題にはるかに高いレベルで取り組みます。これが、Nvidiaの計画が何であるかについての私の完全に主観的な印象です。

1
hc_