CUDA by exampleを読んだときのメモ:第10章「Streams」(書きかけ)
- ここまで、データを並列に処理することでCPUに比べて優れた性能をGPUが示すことを紹介してきた。
- GPUには他の並列処理があって、それはCPUでのタスク並列に似たもの。
- GPUでのタスク処理は、CPUでのそれに比べて手間がかかる/自分で陽に記述してやる必要がある
- この章では、streamの基礎とそれによるタスク並列について学ぶ。
10.1 10章の目的
- ページロックメモリについて学ぶ
- CUDA streamについて学ぶ
- CUDA streamをつかって、アプリを高速化する方法
10.2 ページロックされる、ホストメモリ
- ホストにメモリを確保するには、mallocとcudaHostAllocがある。違いは?
- mallocは標準な、pageable host memoryを割り当てる
- cudaHostAllocはページロックメモリ(pinned memoryとも)を割り当てる
- ページロックメモリは、DMAによるメモリ転送が可能で、それと並行したCPUに依る処理が可能になる
- pageableメモリの転送においても、実際はDMAを介している
- ページロックメモリ転送の方が速い
- 注意点は、ページロックメモリを確保しすぎないこと
- ホストにmallocでメモリを確保した場合とcudaHostAllocで確保した場合で、ホスト・デバイス間での転送速度の違いを調べる簡単なプログラム例を示す
- 速度差はおよそ2倍になる。
- ページロックメモリを確保する利点は、速度が向上するだけではなく、他にも重要な点があり、次節以降で説明する。
10.3 CUDA Streams
- 6章で扱ったCUDAイベント。ストリームを利用していた。
- ストリームを用いることで、高速化が可能になる。
- GPUでの処理を制御できるようになる。
10.4 一つのストリームを使う
- ストリームは複数使って初めて効果があるものだが、まずは一つだけ使用する場合を
- ここでの例。ホストにデータを用意。デバイスに転送。デバイスでカーネル実行。ホストに転送。
- さらに、ホスト→デバイス間のデータ転送を分割して行う。想定されるケースとしては、デバイスのメモリが小さい、とかもありうるからである。
- cudaMemcpyAsync, cudaStreamSynchronizeについて
- GPUの中には、非同期転送をサポートしていないものもある
- 非同期転送での性能向上を調べるため、イベントを作成してtimerを設置
- timerを走らせる前に、ストリームを作成する。その作成方法は単純な物である
- ホスト-デバイス間でのメモリ転送の例。ホストではcudaHostAllocで確保している。
- cudaMemcpyとcudaMemcpyAsyncの違い。メモリ転送を終了して戻るか、終了しないで戻るか。
- 同じストリームにて後ろに存在する命令は、それが始まる前に転送が終わる、という仕様。
- カーネルの起動にて、optimalなストリームの記述を伴っている。最初の、デバイスメモリへの書き込み2つが終了次第、カーネルが起動する。
- 非同期処理が終了次第、同期させるための命令が必要。
- 加えて、ストリームをDestroyする。