comparison paper/data_parallel.tex @ 2:b7c8a956c10b

write benchmark and conclusion
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Wed, 06 Nov 2013 01:16:42 +0900
parents f4b3de446113
children 423b4d15e248
comparison
equal deleted inserted replaced
1:f4b3de446113 2:b7c8a956c10b
1 \section{Cerium における Data 並列}\label{data_parallel} 1 \section{Cerium における Data 並列}\label{data_parallel}
2 データ並列で実行する場合はspawn APIではなく、iterate APIでTaskを生成すればよい。 2 Cerium では,iterate に length を引数として渡し,length の値と渡した引数の個数を次元数として Task 数を Scheduler が計算する。
3 Scheduler内で引数分のTaskを生成し、それぞれに自分が担当するindexをパラメタとして設定していく。 3 それぞれの CPU が担当する index は SchedTask に格納してある。
4 iterateにはlengthを引数として渡し、lengthの値と渡したlengthの個数で次元数や 4 実行時の Task は以下のように記述する。
5 ワークアイテムのサイズをSchedulerが計算する。
6 CPU実行時のkernelは以下のように記述する。
7 5
8 \begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm] 6 \begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm]
9 static int // kernel 7 static int // Task
10 run(SchedTask *s,void *rbuf, void *wbuf) 8 run(SchedTask *s,void *rbuf, void *wbuf)
11 { 9 {
12 float *indata1,*indata2,*outdata; 10 float *indata1,*indata2,*outdata;
13 11
14 indata1 = (float*)s->get_input(rbuf, 0); 12 indata1 = (float*)s->get_input(rbuf, 0);
15 indata2 = (float*)s->get_input(rbuf, 1); 13 indata2 = (float*)s->get_input(rbuf, 1);
16 outdata = (float*)s->get_output(wbuf, 0); 14 outdata = (float*)s->get_output(wbuf, 0);
17 15
18 long i = (long)s->get_param(0); 16 uisigned long i = s->x;
19 outdata[i]=indata1[i]*indata2[i]; 17 outdata[i]=indata1[i]*indata2[i];
20 return 0; 18 return 0;
21 } 19 }
22 \end{Verbatim} 20 \end{Verbatim}
23 21
24 \subsection{データ並列におけるindex割り当ての実装} 22 \subsection{Data 並列における index 割り当ての実装}
25 Taskを生成するとき、dimensionとワークアイテムのサイズをもとに各Taskが担当するindexを計算し、set\_paramする。 23 4 CPU で,一次元で10個の Data に対して Data 並列実行を行った場合,
26 kernelはget\_paramでそのindexを取得してデータ並列で実行する。 24 各 CPU が担当する index は表:\ref{table:data_parallel_index}のようになる。
27 get\_param APIがOpenCLのget\_global\_id APIに相当する。
28 25
29 例として、cpu数4、一次元で10個のdataにたいしてデータ並列実行を行った場合、 26 この例だと各 CPU に対するindexの割り当ては,
30 各CPUが担当するindexは表:\ref{table:data_parallel_index}のようになる。 27 CPU0 は index 0,4,8
31 28 CPU1 は index 1,5,9,
32 この例だと各CPUに対するindexの割り当ては、 29 CPU2 は index 2,6,
33 CPU0はindex0、4、8、 30 CPU3 は index 3,7 となっている。
34 CPU1はindex1、5、9、
35 CPU2はindex2、6、
36 CPU3はindex3、7となっている。
37 31
38 \begin{tiny} 32 \begin{tiny}
39 \begin{table}[h] 33 \begin{table}[h]
40 \begin{center} 34 \begin{center}
41 \caption{data並列実行時のindexの割り当て} 35 \caption{Data 並列実行時の index の割り当て}
42 \label{table:data_parallel_index} 36 \label{table:data_parallel_index}
43 \small 37 \small
44 \begin{tabular}[t]{c||c|c|c|c} 38 \begin{tabular}[t]{c||c|c|c|c}
45 \hline 39 \hline
46 stage&CPU0& CPU1&CPU2&CPU3 \\ 40 stage&CPU0& CPU1&CPU2&CPU3 \\
54 \end{tabular} 48 \end{tabular}
55 \end{center} 49 \end{center}
56 \end{table} 50 \end{table}
57 51
58 \end{tiny} 52 \end{tiny}
59 この実装により、Ceriumでデータ並列の実行が可能になった。 53 この実装により,Cerium で Data 並列実行が可能になった。
60 並列プログラミングだと、並列化するTaskが全部同一であるという事は少なくない。 54 並列プログラミングだと,並列化する Task が全部同一であるという事は少なくない。
61 その際、Taskを生成する部分をループで回すことなく、簡単なsyntaxで記述できる。 55 iterate を使用することで,Task を生成する部分をループで回すことなく,簡単な syntax で記述できる。
62
63 データ並列で実行する場合は、inputとoutputを各Taskで共有するため、少ないコピーですむ。
64 CPUならメモリ領域がTaskとmanagerで同じなので、dataのコピーで大きいオーバーヘッドにはならない。
65 しかしCellとGPUはメモリ領域が異なるため、dataコピーのオーバーヘッドが大きく、
66 データ並列による高速化が見込める。