Mercurial > hg > Members > kokubo > 2013-mid-thesis
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 データ並列による高速化が見込める。 |