Your SlideShare is downloading. ×
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
GTC2011 Japan
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

GTC2011 Japan

412

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
412
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • みなさん、CUDAチュートリアル第二弾、CUDA30分クッキングへようこそ。\nぼくはフィックスターズという会社でプログラマをしています、飯塚と申します。どうぞよろしくお願いします。\n\nさて、いまここにいるみなさんは、CUDAをこれから学ぶ、あるいは既に学んでいる方だと思われます。このチュートリアルの目的は、CUDAプログラミングという敷居がどれくらいの高さなのか、実感として知っていただくことです。ここで紹介するツールやテクニックは現場で使われているものであり、CUDAの使用を検討している方、今まさに学習中の方には、必ず役に立つものと信じています。\n\n\n\n\n\n
  • それでは、本日のメニューをご紹介します。\n\n前菜は、CUDA環境構築です。CUDAプログラミングを行うに当たって、何が必要なのかを簡単にご説明します。メイン1皿目には、配列をxxするプログラム、というものをゼロから実装します。メイン2皿目には、C++で実装されたリアルタイムレイトレーシングプログラムをCUDAに移植します。そしてデザートには、簡単にパフォーマンス測定を行います。\n
  • 早速、CUDAプログラミングの環境構築を行っていきましょう。\n
  • 今回はWindowsにおけるお手軽CUDAプログラミング環境を構築します。\n材料はこちらの通り。ドライバ、ツールキット、SDK、Visual Studioなどホストコードのコンパイラ、またクロスプラットフォームなビルドシステムCMakeを導入します。\n\n= Live =\nといっても難しいことはなく、このようにWebページからインストーラをダウンロードし、ワンクリックでインストールを行うだけです。\n\n
  • WindowsやMacなら、このとおりインストーラを4, 5発実行して、おまけに再起動するくらいですみます。Linux環境だとドライバのインストール周りでもう少し複雑なのですが、これについては弊社のCUDA Information siteにてインストール手順を公開していますので、ご参考にしていただければと思います。\n
  • さて、これでCUDAプログラミング環境は整いました。次はいよいよプログラミングの時間です。\n
  • お題は、ゼロからGPUプログラムを作りましょう・・・です。\n今回は、配列に対して任意の操作を関数オブジェクトとして実装し、これを実行するGPUプログラムを作成してみます。\n\n材料として、いくつかのCUDA APIとCUDAの文法を覚えておきましょう。\nまた、C++ templateとよくできたエディタ、よくできたキーボードも必要です。\n\nちなみに僕にとっての「よくできた」はvimとHappy Hacking Keyboardなのですが・・・\n時間もないのでこれについてのの議論はまたいつか。\n\n= Live =\n1.CMakeLists.txtをつくる\n2. mainかく\n
  • さて、CUDA APIとCUDAの拡張構文についてですが、必要なのは全部でたった4つです。\nGPUは専用のメモリ空間を持っており、このメモリ空間のアロケーションに使用するのがcudaMallocとcudaFreeです。\nまた、CPU側のメモリとの間のデータのコピーはcudaMemcpyというAPIを使用します。\n\nそして、カーネルと呼ばれるGPUプログラムの呼び出しには、CUDAの拡張文法を使用します。\nこのようにアングルブラケットをカーネル関数の前に付け、nvccでコンパイルすると、\nカーネルの呼び出しとして解釈されます。\n\n= Live =\nCUDA APIを使用したホストコードを作成する\n
  • さて、CUDAスレッドとカーネルという言葉が出てきましたね。これについて説明します。\n\nGPUは、数万というCUDAスレッドを数百のCUDAコアで並列処理するという実行モデルを持っています。CUDAカーネルは、CUDAスレッドの処理内容を記述するためのもので、__global__という識別子を関数の先頭に付けると、それがCUDAカーネルになります。\n\n= Live =\nCUDAカーネルのスタブを書く\n
  • CUDAカーネル内部では、いくつかの特殊な組み込み関数や変数が使用できます。今回は、threadIdxという組み込み変数のみを使用します。この変数は、そのカーネルを実行するCUDAスレッドのIDを格納しており、CUDAスレッドごとに違う変数を取得できます。\n\n= Live =\nカーネルを実装\n関数オブジェクトを実装し、関数に__device__識別子を付ける\n
  • さて、CUDAを使用した簡単なコードを作成しました。たった50行のコードです。また、ホスト側はメモリ領域が連続していればSTLでも問題ありません。またカーネル呼び出しではC++ templateを使用できるため、柔軟なプログラミングが可能なことがわかりました。\n\nまた、このコードですが、実行されるロジックのほとんどを、CPUとGPUで共有することが可能です。これによって、デバッグしやすい、保守しやすい、またこれは特にチューニングいない場合に限りますが、パフォーマンス比較がしやすい、などのメリットがあります。\n\n= Live =\ncpu_gpu_vecxx.cuを見せる\n\n
  • それでは、メイン2皿目、リアルタイムレイトレーシングについて。\n\n
  • ここに、C++で書かれたプログラムがあります。これをGPUに移植しようというのが、今回のテーマです。\n\n= Live =\n1. buildはしておく\n2. ./cpu_rendererするだけ\n
  • レイトレーシングは、その名のとおり、視点から仮想スクリーンに対する光線を追跡して3Dモデルを2Dにマッピングするものです。この絵にはレイは一本しか書かれていませんが、最低でもスクリーンのピクセル数のレイを追跡する必要があります。\n
  • このプログラムのおおまかな作りはこちら。DrawImageのcomputeメソッドがピクセルごとにSceneクラスのrender()メソッドを呼び出します。Sceneには複数のレンダリング対象オブジェクトが含まれており、Primitiveインタフェースを通じて必要なメソッドを呼び出します。\n
  • 今回は、Sceneクラス以下すべてをCUDA化します。これを行うために、どのくらいの作業が必要になるのでしょうか?では早速やっていきましょう。\n\n= Live =\n1. CMakeLists.txtひらき、CUDA_NVCC_FLAGSに-D USE_CUDA -arch=sm_20をセットし、cuda_add_executableする\n2. porting.h をひらき、FUNC_DECLに__host__ __device__つける\n3. main.cpp を main.cuにコピーする\n4. DrawImageにd_image_を追加する\n5. DrawImage::initにcudaMalloc(&d_image...)とcudaMemset(d_image...)かく\n6. DrawImage::finishにcudaFree(d_image)をかく\n\n
  • さて、ここでわかるとおり、Scene以下をCUDA化するのですから、CUDAカーネル内部でC++のオブジェクトを生成できなくてはなりません。ここで、CUDA4.0からサポートされたnew/deleteが活躍します。\n\n= Live =\n1. DrawImageにd_scene_p_を追加\n2. グローバル空間にnew_kernelとdelete_kernelを追加\n3. DrawImage::initにcudaMalloc(&d_scene_p_, ...)とnew_kernelの呼び出しをかく\n4. DrawImage::finishにcudaFree(d_scene_p_)とdelete_kernelの呼び出しをかく\n5. グローバル空間にrender_kernelとdisplace_light_kernelをかく\n5. DrawImage::computeにrender_kernelの呼び出しをかく\n6. DrawImage::displace_lightにdisplace_light_kernelの呼び出しをかく\n\nビルドして動かす\n\n
  • さて、ポイントですが、今回行った作業はわずか50行程度のコードの追加です。Scene以下のコードは1行も触っていないことにお気づきですか?肝心のレンダリングロジックは、CPUとGPUで完全にコードを共有しています。\n\nこれができたのも、CUDA4.0でC++サポートがだいぶ拡充されたことが理由の一つです。SDKにnewdeleteというサンプルコードがあるので、興味のある方はそちらもみてみてください。\n
  • さて、最後にパフォーマンスの測定を行います。\n
  • パフォーマンス測定に使うのは先程移植したのレンダラです。せっかくCUDAにしたのだから、そのスピードを数字としてみたいですよね。今回はFPSとして、つまり一秒間に何枚レンダリングできたのか、画面上に表示してみることにします。\n\n= Live = \n1. display_callbackにPerformance perf(“all”)を宣言、compute()とdisplay()のあとでperf.stop()して、1e3fをperf_mean_ms()でわり、fpsとする\n2. stringstream ssに適当に文字列として突っ込み、glutSetWindowtitle(ss.str().c_str())する\n3. ビルドしてcpu版とgpu版を比べる。10倍くらい違うハズ\n
  • 今回はfps、つまり単純な計算時間という形でパフォーマンスを表示しましたが、本当に大事なのは計算時間のうち、どのような処理がどのくらいの割合を占めるのかということです。これについては、第3、4チュートリアルで紹介されるプロファイリングツールが役立ちます。興味のある方は是非御覧ください。\n
  • フリーランチ、つまり努力せずプログラムが早くなる夢の時間は終わり、少しの手間で、美味しいディナーを食べる時が来ました。次はみなさんの番です。\n
  • C/C++を知っていれば、CUDAプログラミングは難しくありません。簡単に動かすだけであれば、最低限の努力で達成可能な場合もあります。\n\n最後になりますが、今回使用したソースコードは以下で公開しています。\n
  • それではみなさん、よいプログラミングを!\n
  • Transcript

    • 1. CUDA入門 CUDA30分クッキング株式会社フィックスターズプログラマ 飯塚拓郎
    • 2. 本日のメニュー単色 Antipasto CUDA環境構築 Primo Piatto 配列をxxする Second Piatto リアルタイムレイトレーシング Dolce パフォーマンス測定
    • 3. Antipasto CUDA環境構築単色
    • 4. Antipasto CUDA環境構築✓ お題単色 - Windowsでお手軽CUDAプログラミング環境を整えましょう✓ 材料 - NVIDIA Driver : NVIDIA GPUのドライバ - NVIDIA CUDA Toolkit : CUDAコンパイラ、ランタイムライブラリ等 - NVIDIA GPU Computing SDK : サンプルコード、ユーティリティ等 - Visual Studio 20xx : ホストコードのコンパイラ - CMake(お好みで) : クロスプラットフォームなビルドシステム
    • 5. Antipasto CUDA環境構築単色✓ Cooking Point - Windowsならインストーラ4, 5個 - Macでもほとんど同じ One More Thing ... - Linuxディストリビューションのインストールチュートリアルはこちら - http://gpu.fixstars.com/index.php/CUDAのインストール
    • 6. Primo Piatto 配列をxxする単色
    • 7. Primo Piatto 配列をxxする単色✓ お題 - ゼロからGPUプログラム作りましょう✓ 材料 - cudaMalloc - cudaFree - cudaMemcpy - <<<>>> - C++ template、よくできたエディタ、よくできたキーボード
    • 8. CUDA APIとCUDA構文✓ メモリアロケーション単色 - cudaMalloc(void** devPtr, size_t size) - cudaFree(void* devPtr)✓ メモリコピー - cudaMemcpy(void* dst, void* src, size_t size, enum cudaMemcpyKind kind) カーネル呼び出し - <<<1, threadNum>>>kernel_name(...) - kernel_nameというカーネルをtheadNum個のCUDAスレッドで実行す
    • 9. CUDAスレッドとカーネル単色 CUDAカーネルには 各スレッドの処理を記述 CUDAスレッドは CUDAカーネルを実行 CUDAコアは CUDAスレッドを順次実行
    • 10. CUDAカーネル✓ 今回のカーネルを書く上で覚えなきゃいけないこと単色 - dim3 threadIdx - CUDAカーネルの組み込み変数で、スレッドIDが格納されます - スレッド空間が一次元なら、threadIdx.xがスレッドIDになる これだけ!
    • 11. Primo Piatto 配列をxxする単色✓ Cooking Point - ホスト側はメモリ領域が連続していることが保証できていればSTLでもOK - c++ templateで汎用性もバッチリ - たった50行 One More Thing ... - これってGPUのコードがほとんどそのままホストコードとして動きます
    • 12. Second Piatto リアルタイムレイトレーシング単色
    • 13. Second Piatto リアルタイムレイトレーシング単色✓ お題 - C++なCPUコードをCUDA化しましょう✓ 材料 - 並列化できそうなCPUコード
    • 14. レイトレーシングについて単色 光源 レンダリング対象物 視点 レイ 仮想スクリーン
    • 15. 設計図単色 Sceneは複数の Scene Primitive Primitiveをもつ -------------- ---------- --- -- Pixel render(int x, intersect() = 0 ピクセルごとに Primitiveインタフェースを rende()を呼び出す 実装 DrawImage Sphere Triangle ---------- -------- -------- -- compute() - -
    • 16. 設計図 ここ全部CUDA化単色 Scene Primitive -------------- ---------- --- -- Pixel render(int x, intersect() = 0 DrawImage Sphere Triangle ---------- -------- -------- -- compute() - -
    • 17. CUDA カーネル C++ compatibility単色✓ CUDA3.xまでは・・・ - リソースアロケーションとかできない - そもそも本当の意味でのfunction callはできなかった - (関数は全部inline)✓ CUDA4.0では・・・ - カーネル内部でnew/delete可能! - function callが実装され、virtualが使えるようになった!
    • 18. Second Piatto リアルタイムレイトレーシング単色✓ Cooking Point - 全体が約1700行、うち50行程度を追加しただけ - ループを見よ!CUDAで並列化できるところは大体ループ✓ One More Thing - CUDAのC++サポートが大分いい感じ - SDKのnewdeleteというサンプルにスレッドセーフなコンテナの実装アリ
    • 19. Dolce パフォーマンス測定単色
    • 20. Dolce パフォーマンス測定単色✓ お題 - パフォーマンスを測ってみましょう✓ 材料 - 十分な精度のタイマ関数(とそのユーティリティ) - さっきのレイトレーシングプログラム
    • 21. Dolce パフォーマンス測定✓ Cooking Point単色 - パフォーマンス測定値は見やすい形で!✓ One More Thing - パフォーマンスメトリクス - ベースとなるのは計算時間 - 重要なのは、計算時間のうち何がどのくらい占めているのかということ - 計算がネック:compute bound - 転送がネック:memory bound
    • 22. Free Lunch is Over, Let s Have a Dinner !単色
    • 23. Free Lunch is Over, Let s Have a Dinner !単色✓ Cooking Point - C/C++を知っていれば、CUDAプログラミングはむずかしくない - 既存のソースコードも、動かすだけなら最低限の努力でOK✓ One More Thing - 今回使用したソースコードを公開します - http://github.com/iitaku/gtc2011
    • 24. Happy Programming, Everyone !

    ×