annotate cerium_gpu.tex @ 2:bff486ef0e8c

commit
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Mon, 21 Apr 2014 03:30:37 +0900
parents a0fad656a7ea
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
5153d23a38e6 first commit
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 \section{Cerium の GPGPU への対応}
1
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2 本章では、まずはじめに GPU プログラミングの特徴および問題について述べ、Cerium への実装でどのように対応したかについて説明する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
3
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
4 \subsection{GPU プログラミングの特徴および問題}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
5 まず Multi Core CPU に対するプログラミングと同様に性能を向上させるためには、プログラム全体を対象とした並列度を高くしなければならない。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
6 明示的な並列化部分はループ部分である。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
7 GPU は数百個のコアを有しており、ループ部分に対してデータ並列で処理を行うことで CPU より高速で演算を行うことができる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
8 プログラムの大部分がループであれば、データ並列による実行だけでプログラムの性能は向上する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
9 しかし、多くのプログラムはその限りではない。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
10 GPGPU においてネックになる部分はデータ転送である。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
11 GPU の Memory 空間(図:\ref{fig:gpuarch})は CPU(図:\ref{fig:cpuarch}) とは異なり、Shared Memory ではないため host と device 間でデータの共有ができない。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
12 データにアクセスするためには Memory 空間ごとコピーするしかない。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
13 これが大きなオーバーヘッドになるので、データ転送をオーバーラップする必要がある。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
14 今回新たに、データ転送を自動でオーバーラップするように OpenCL および CUDA を用い Scheduler を実装した。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
15
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
16 \begin{figure}[htpd]
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
17 \begin{center}
2
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
18 \includegraphics[scale=0.35]{./images/gpu_arch.pdf}
1
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
19 \end{center}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
20 \caption{Gpu Architecture}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
21 \label{fig:gpuarch}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
22 \end{figure}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
23
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
24 \begin{figure}[htpd]
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
25 \begin{center}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
26 \includegraphics[scale=0.7]{./images/cpu_arch.pdf}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
27 \end{center}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
28 \caption{Cpu Architecture}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
29 \label{fig:cpuarch}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
30 \end{figure}
2
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
31
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
32 \subsection{OpenCL および CUDA を用いた Scheduler の実装}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
33 Scheduler と CpuThreads に対応させる形で OpenCL を用いた GpuScheduler, GpuThreads、CUDA を用いた CudaScheduler, CudaThreads を実装した。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
34 TaskManager から転送された TaskList の情報をもとに device 上のメモリ領域を確保する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
35 その後、OpenCL ならば CommandQueue、CUDA ならば Stream に Operation を発行していく。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
36 Operation は発行された順序で実行されるので、host から device へのデータ転送、kernel の実行、device から host へのデータ転送の順に発行する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
37 非同期 API を用いることでデータ転送や kernel の実行を並列に行うことができる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
38 通常、非同期 API を用いる場合は依存関係を考慮した同期が必要になるが転送されてくる Task の依存関係は TaskManager ですべて解消されているので Scheduler 側では順番を考えず Task を実行して問題ない。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
39 host から device へのデータ転送は、OpenCL では clEnqueueWriteBuffer、CUDA では cuMempcyHtoDAsync を用いて行われる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
40 clEnqueueWriteBuffer は第三引数に CL\_FALSE を指定することで非同期なデータ転送を行う。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
41 転送されてきた TaskList からデータ並列またはタスク並列で実行するか決定する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
42 データ並列で実行する場合は、OpenCL では clEnqueueTaskNDRangeKernel、CUDA では cuLaunchKernel を用いる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
43 タスク並列で実行する場合は、OpenCL では clEnqueueTask、CUDA では cuLaunckKernel の引数を1に設定することで実行することができる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
44 device から host へのデータ転送は、OpenCL では clEnqueuReadBuffer、CUDA では cuMemcpyDtoHAsync を用いて行われる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
45 clEnqueueReadBuffer も clEnqueueWriteBuffer と同様に第三引数に CL\_FALSE を指定することで非同期実行となる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
46 転送されてきた Task がすべて終了すると Synchronized Queue である mail を通して TaskManager に Task の終了を通知する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
47 終了が通知されると TaskManager で依存関係が解消し、再び TaskList を転送する。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
48 GpuScheduler および CudaScheduler は複数の CommandQueue および Stream を持っており、パイプラインで実行される。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
49
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
50 kernel の記述は以下のようになる。
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
51 \lstinputlisting[caption=multiply(OpenCL),label=test]{./source/Multi.cl}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
52 \lstinputlisting[caption=multiply(CUDA),label=test]{./source/Multiply.cu}
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
53
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 1
diff changeset
54 修飾子など若干の違いはあるが、ほぼ同じ記述で書くことができるが CPU, OpenCL, CUDA のどれか1つの記述から残りのコードも生成できるようにすることが望ましい。