CUDA C プロフェッショナル プログラミング


CUDA C プロフェッショナル プログラミング (impress top gear)


インプレス


著者:John Cheng、Max Grossman、Ty McKercher
訳者:株式会社クイープ
監訳:森野慎也


本書に寄せて
まえがき
はじめに
謝辞

第1章 CUDA によるヘテロジニアス並列コンピューティング
1.1 並列コンピューティング
1.1.1 逐次プログラミングと並列プログラミング
1.1.2 並列化
1.1.3 コンピュータアーキテクチャ
1.2 ヘテロジニアスコンピューティング
1.2.1 ヘテロジニアスアーキテクチャ
1.2.2 ヘテロジニアスコンピューティングのパラダイム
1.2.3 CUDA:ヘテロジニアスコンピューティングのためのプラットフォーム
1.3 Hello World from GPU
1.4 CUDA Cプログラミングは難しい?
1.5 まとめ

第2章 CUDAプログラミングモデル
2.1 CUDAプログラミングモデルの概要
2.1.1 CUDAプログラミングの構造
2.1.2 メモリの管理
2.1.3 スレッドの構成
2.1.4 カーネルの起動
2.1.5 カーネルの作成
2.1.6 カーネルの検証
2.1.7 エラー処理
2.1.8 コンパイルと実行
2.2 カーネルの所要時間の計測
2.2.1 CPUタイマーによる計測
2.2.2 nvprofによる計測
2.3 並列スレッドの構成
2.3.1 ブロックとスレッドによる行列のインデックス付け
2.3.2 2次元グリッドと2次元ブロックによる行列の加算
2.3.3 1次元グリッドと1次元ブロックによる行列の加算
2.3.4 2次元グリッドと1次元ブロックによる行列の加算
2.4 デバイスの管理
2.4.1 CUDA Runtime APIを使ったGPU情報の取得
2.4.2 最適なGPUの特定
2.4.3 nvidia-smiを使ったGPU情報の取得
2.4.4 実行時のデバイスの設定
2.5 まとめ

第3章 CUDAの実行モデル
3.1 CUDAの実行モデルの紹介
3.1.1 GPUアーキテクチャの概要
3.1.2 Fermiアーキテクチャ
3.1.3 Keplerアーキテクチャ
3.1.4 プロファイルに基づく最適化
3.2 ワープ実行の特性
3.2.1 ワープとスレッドブロック
3.2.2 ワープダイバージェンス
3.2.3 リソースの分割
3.2.4 遅延の隠ぺい
3.2.5 占有率
3.2.6 同期
3.2.7 スケーラビリティ
3.3 並列性の確保
3.3.1 nvprofによるアクティブワープのチェック
3.3.2 nvprofによるメモリ操作のチェック
3.3.3 並列性をさらに向上させる
3.4 分岐のダイバージェンスの回避
3.4.1 並列リダクションの問題
3.4.2 並列リダクションでのダイバージェンス
3.4.3 並列リダクションでのダイバージェンスの改善
3.4.4 インターリーブペアによるリダクション
3.5 ループの展開
3.5.1 展開によるリダクション
3.5.2 ワープ展開によるリダクション
3.5.3 完全な展開によるリダクション
3.5.4 テンプレート関数によるリダクション
3.6 ダイナミックパラレリズム
3.6.1 ネストされた実行
3.6.2 GPUでのネストされたHello World
3.6.3 ネストされたリダクション
3.7 まとめ

第4章 グローバルメモリ
4.1 CUDAのメモリモデルの紹介
4.1.1 メモリ階層のメリット
4.1.2 CUDAのメモリモデル
4.2 メモリの管理
4.2.1 メモリの確保と解放
4.2.2 メモリ転送
4.2.3 ピンメモリ
4.2.4 ゼロコピーメモリ
4.2.5 UVA
4.2.6 ユニファイドメモリ
4.3 メモリアクセスパターン
4.3.1 アラインアクセスとコアレスアクセス
4.3.2 グローバルメモリの読み取り
4.3.3 グローバルメモリの書き込み
4.3.4 AoSとSoA
4.3.5 パフォーマンスチューニング
4.4 カーネルの帯域幅の調整
4.4.1 メモリ帯域幅
4.4.2 行列転置の問題
4.5 ユニファイドメモリを使った行列の加算
4.6 まとめ

第5章 シェアードメモリとコンスタントメモリ
5.1 CUDAのシェアードメモリの紹介
5.1.1 シェアードメモリ
5.1.2 シェアードメモリの確保
5.1.3 シェアードメモリのバンクとアクセスモード
5.1.4 シェアードメモリの容量の設定
5.1.5 同期
5.2 シェアードメモリのデータレイアウトの確認
5.2.1 正方形のシェアードメモリ
5.2.2 長方形のシェアードメモリ
5.3 グローバルメモリへのアクセスの削減
5.3.1 シェアードメモリを使った並列リダクション
5.3.2 展開を使った並列リダクション
5.3.3 動的なシェアードメモリを使った並列リダクション
5.3.4 実質的な帯域幅
5.4 グローバルメモリへのアクセスのコアレッシング
5.4.1 基準となる転置カーネル
5.4.2 シェアードメモリを使った行列転置
5.4.3 パディングされたシェアードメモリを使った行列転置
5.4.4 展開を使った行列転置
5.4.5 並列性の改善
5.5 コンスタントメモリ
5.5.1 コンスタントメモリを使った1次元のステンシルの実装
5.5.2 リードオンリーキャッシュとの比較
5.6 ワープシャッフル命令
5.6.1 さまざまなワープシャッフル命令
5.6.2 ワープ内でのデータの共有
5.6.3 ワープシャッフル命令を使った並列リダクション
5.7 まとめ

第6章 ストリームと並列処理
6.1 ストリームとイベントの紹介
6.1.1 CUDAのストリーム
6.1.2 ストリームのスケジューリング
6.1.3 ストリームの優先度
6.1.4 CUDAのイベント
6.1.5 ストリームの同期
6.2 カーネルの並列実行
6.2.1 非NULLストリームでのカーネルの並列実行
6.2.2 Fermi GPUでの偽の依存関係
6.2.3 OpenMPを使ったタスクのディスパッチ
6.2.4 環境変数を使ったストリームの振る舞いの調整
6.2.5 並列性を制限するGPUリソース
6.2.6 デフォルトストリームのブロッキング
6.2.7 ストリーム間の依存関係の作成
6.3 カーネル実行とデータ転送のオーバーラップ
6.3.1 深さ優先のスケジューリングを使ったオーバーラップ
6.3.2 幅優先のスケジューリングを使ったオーバーラップ
6.4 GPUとCPUの実行のオーバーラップ
6.5 ストリームのコールバック
6.6 まとめ

第7章 命令レベルのプリミティブの調整
7.1 CUDA命令の概要
7.1.1 浮動小数点命令
7.1.2 組み込み関数と標準関数
7.1.3 アトミック命令
7.2 アプリケーションに合わせた命令の最適化
7.2.1 単精度と倍精度
7.2.2 標準関数と組み込み関数
7.2.3 アトミック命令の詳細
7.2.4 アプリケーションへの応用
7.3 まとめ

第8章 CUDAのGPUアクセラレーションライブラリとOpenACC
8.1 CUDAライブラリの紹介
8.1.1 CUDAライブラリがサポートしている分野
8.1.2 ライブラリに共通するワークフロー
8.2 cuSPARSEライブラリ
8.2.1 cuSPARSEライブラリのデータ格納フォーマット
8.2.2 cuSPARSEライブラリでのフォーマットの変換
8.2.3 cuSPARSEライブラリのサンプルの実行
8.2.4 cuSPARSEライブラリを使った開発上の注意点
8.2.5 cuSPARSEライブラリのまとめ
8.3 cuBLASライブラリ
8.3.1 cuBLASライブラリでのデータの管理
8.3.2 cuBLASライブラリのサンプルの実行
8.3.3 cuBLASライブラリを使った開発上の注意点
8.3.4 cuBLASライブラリのまとめ
8.4 cuFFTライブラリ
8.4.1 cuFFTライブラリのAPIの使用
8.4.2 cuFFTライブラリのサンプルの実行
8.4.3 cuFFTライブラリのまとめ
8.5 cuRANDライブラリ
8.5.1 疑似乱数と準乱数の選択
8.5.2 cuRANDライブラリの概要
8.5.3 cuRANDライブラリのサンプルの実行
8.5.4 cuRANDライブラリを使った開発上の注意点
8.6 CUDA 6で導入されたCUDAライブラリの機能
8.6.1 CUDAのドロップインライブラリ
8.6.2 マルチGPUライブラリ
8.7 CUDAライブラリのパフォーマンスの調整
8.7.1 cuSPARSEとMKL
8.7.2 cuBLASとMKL BLAS
8.7.3 cuFFT、FFTW、MKLの比較
8.7.4 CUDAライブラリのパフォーマンスのまとめ
8.8 OpenACCの使用
8.8.1 OpenACCのコンピュートディレクティブの使用
8.8.2 OpenACCのデータディレクティブの使用
8.8.3 OpenACC Runtime API
8.8.4 OpenACCとCUDAライブラリの結合
8.8.5 OpenAACのまとめ
8.9 まとめ

第9章 マルチGPUプログラミング
9.1 マルチGPUへの移行
9.1.1 複数のGPUでの実行
9.1.2 ピアツーピア(P2P)通信
9.1.3 複数のGPUの同期
9.2 複数のGPUの間で計算処理を分割する
9.2.1 複数のデバイスでメモリを確保する
9.2.2 1つのホストスレッドの処理を分割する
9.2.3 コンパイルと実行
9.3 複数のGPUでのピアツーピア通信
9.3.1 P2P通信の有効化
9.3.2 P2Pメモリ転送
9.3.3 UVAを使ったP2Pメモリアクセス
9.4 マルチGPUでの有限差分法
9.4.1 2次元波動方程式のステンシル計算
9.4.2 マルチGPUプログラムの典型的なパターン
9.4.3 複数のGPUを使った2次元のステンシル計算
9.4.4 計算と通信のオーバーラップ
9.4.5 コンパイルと実行
9.5 GPUクラスタでのアプリケーションのスケーリング
9.5.1 CPUからCPUへのデータ転送
9.5.2 従来のMPIを使ったGPUからGPUへのデータ転送
9.5.3 CUDA対応MPIを使ったGPUからGPUへのデータ転送
9.5.4 CUDA対応MPIを使った同一ノード内でのGPUからGPUへのデータ転送
9.5.5 メッセージのチャンクサイズの調整
9.5.6 GPUDirect RDMAを使ったGPUからGPUへのデータ転送
9.6 まとめ

第10章 実装上の注意点
10.1 CUDA Cの開発プロセス
10.1.1 APOD開発サイクル
10.1.2 最適化の機会
10.1.3 CUDAコードのコンパイル
10.1.4 CUDAのエラー処理
10.2 プロファイルに基づく最適化
10.2.1 nvprofを使って最適化の機会を捉える
10.2.2 nvvpを使った最適化のガイドライン
10.2.3 NVIDIA Tools Extension(NVTX)
10.3 CUDAのデバッグ
10.3.1 カーネルのデバッグ
10.3.2 メモリのデバッグ
10.3.3 デバッグのまとめ
10.4 ケーススタディ:CUDA CへのCプログラムの移植
10.4.1 cryptの評価
10.4.2 cryptの並列化
10.4.3 cryptの最適化
10.4.4 cryptのデプロイメント
10.4.5 cryptの移植のまとめ
10.5 まとめ

付録A 参考文献

書籍目次

Posted by shi-n