Mercurial > hg > Papers > 2015 > yuhi-master
changeset 50:d4be7f4b9a73
add Gpu pipeline
author | Yuhi TOMARI <yuhi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 17 Feb 2015 05:07:25 +0900 |
parents | c7678996940c |
children | e2790efcd306 8057614d5b77 |
files | paper/chapter5.tex paper/chapter6.tex paper/master_paper.pdf paper/master_paper.toc |
diffstat | 4 files changed, 116 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/chapter5.tex Tue Feb 17 03:53:19 2015 +0900 +++ b/paper/chapter5.tex Tue Feb 17 05:07:25 2015 +0900 @@ -30,12 +30,105 @@ Scheduler は依存関係を考慮せずに実行して問題ない。 GPGPU 用の Scheduler は CommandQueue を2つ持っており、Task をパイプライン的に実行する。 +GpuScheduler のパイプライン処理部分をソースコード:\ref{src:pipeline_gpu}に示す。 +\newpage +\begin{lstlisting}[frame=lrbt,label=src:pipeline_gpu,caption=GpuSchedulerにおけるパイプライン処理,numbers=left] +void +GpuScheduler::run() { + for (;;) { + memaddr params_addr = connector->task_list_mail_read(); + // read task list mail from DmaManager + + while (params_addr) { + // since we are on the same memory space, we don't has to use dma_load here + tasklist = (TaskListPtr)connector->dma_load(this, params_addr,sizeof(TaskList), + DMA_READ_TASKLIST); + + for (TaskPtr nextTask = tasklist->tasks; nextTask < tasklist->last(); + nextTask = nextTask->next()) { + + kernel[cur] = clCreateKernel(program, function, &ret); -転送されてきた Task が全て終了すると、 + int param = 1; + for(int i=0;i<nextTask->inData_count;i++) { + ListElement *input_buf = nextTask->inData(i); + if (input_buf->size==0) break; + createBuffer(&memin[cur], param, context, mem_flag, input_buf->size, &ret); + ret = clEnqueueWriteBuffer(command_queue[cur], memin[cur].buf[param], + CL_FALSE, 0, input_buf->size, + input_buf->addr, 0, NULL, NULL); + ret = clSetKernelArg(kernel[cur], param, sizeof(memaddr), + (void *)&memin[cur].buf[param]); + param++; + } + memin[cur].size = param; // +1 means param + + for(int i = 0; i<nextTask->outData_count;i++) { // set output data + ListElement *output_buf = nextTask->outData(i); + if (output_buf->size==0) break; + createBuffer(&memout[cur], i, context, CL_MEM_WRITE_ONLY, output_buf->size, &ret); + ret = clSetKernelArg(kernel[cur], param, + sizeof(memaddr), (void *)&memout[cur].buf[i]); + param++; + } + memout[cur].size = param - memin[cur].size; + + ret = clEnqueueTask(command_queue[cur], kernel[cur], 0, NULL, NULL); + + for(int i=0;i<nextTask->outData_count;i++) { // read output data + ListElement *output_buf = nextTask->outData(i); + if (output_buf->size==0) break; + GpuBufferPtr mem = memout ; + ret = clEnqueueReadBuffer(command_queue[cur], mem[cur].buf[i0], CL_FALSE, 0, + output_buf->size, output_buf->addr, 0, + NULL,&memout[cur].event[i]); + } + cur++; + if (STAGE <= cur) cur = 0; + wait_for_event(kernel_event, memout, tasklist, cur); + } + reply = (memaddr)tasklist->waiter; + params_addr = (memaddr)tasklist->next; + } + + wait_for_event(kernel_event, memout, tasklist, cur); + + unsigned long long wait = 0; + (*connector->end_dmawait_profile)(&wait, &(connector->start_time), &(connector->stop_time)); + connector->mail_write((memaddr)MY_SPE_STATUS_READY); + } + /* NOT REACHED */ +} + +\end{lstlisting} + +\begin{itemize} +\item 4行目 : DMAManager から tasklist mail を取得 +\item 9行目 : 取得した mail から TaskList を read をする。 + TaskList に格納されている Task 全てを実行し終わるまでループする +\item 15行目 : 二段のパイプラインを形成するため、kernel を2つ持作る +\item 18行目 : パイプラインの read 部分。input データを全て kernel の引数として MemoryBuffer に書き込み、 + kernel に Buffer をset する +\item 31行目 : Output データを書き込む MemoryBuffer を用意し、kernel にset している。 +\item 40行目 : パイプラインの exec 部分。kernel を実行する +\item 42行目 : パイプラインの write 部分。kernel は実行した結果を MemoryBuffer に書き込む。 + MemoryBuffer に書き込まれた値をここで読み出している。 +\item 52行目 : パイプラインのステージの切り替えを行っている。 + wait\_for\_event 内で依存関係を解決したら実行の終わったステージの MemoryBuffer を delete し、次のステージへ移行する +\item 55行目 : 次の task を読み出し、このループを終了する +\end{itemize} + +DMAManager から転送されてきた Task を読み込み、Input/Output データを取り出す。 +データは OpenCL の API を介して GPU の MemoryBuffer に送信され、kernel が実行される。 +実行終了後は MemoryBuffer から戻り値を読み取り、Cerium に Output データとして返している。 +一連の処理は CommandQueue を介して GPU で実行される。 +GpuScheduler は CommandQueue を2つ持っており、二段のパイプラインが形成される。 + +全ての Task が終了すると、 TaskManager 間の通信を担当する同期キューである mail を通して TaskManager に Task の終了を通知する。 -終了が通知されると TaskManager でその TaskList に関する依存関係が解消され、 +終了が通知されると TaskManager でその TaskList に関する依存関係が解消される。 -GPGPU の Scheduler 内で Platform や Device ID の取得、 Context の生成、 Kernel の Build と Load等も行っており、OD +Scheduler 内で Platform や Device ID の取得、 Context の生成、 Kernel の Build と Load等も行っており、 並列処理したい計算のみに集中できる。 \section{データ並列}
--- a/paper/chapter6.tex Tue Feb 17 03:53:19 2015 +0900 +++ b/paper/chapter6.tex Tue Feb 17 05:07:25 2015 +0900 @@ -136,7 +136,7 @@ \includegraphics[scale=0.7]{./images/iothread.pdf} \end{center} \caption{IO Thread による BlockedRead} - \label{fig:iothread__blockedread} + \label{fig:iothread_blockedread} \end{figure} IO\_0 で実行される Task は BlockedRead のみなので、 IO\_0 のpriority を高く設定することで Blocked Read は連続で実行される。
--- a/paper/master_paper.toc Tue Feb 17 03:53:19 2015 +0900 +++ b/paper/master_paper.toc Tue Feb 17 05:07:25 2015 +0900 @@ -21,22 +21,22 @@ \contentsline {section}{\numberline {5.3}データ並列}{20} \contentsline {chapter}{\numberline {第6章}GPGPU への対応}{23} \contentsline {section}{\numberline {6.1}OpenCL および CUDA による実装}{23} -\contentsline {section}{\numberline {6.2}データ並列}{24} -\contentsline {chapter}{\numberline {第7章}並列処理向けI/O}{26} -\contentsline {section}{\numberline {7.1}mmap}{26} -\contentsline {section}{\numberline {7.2}Blocked Read による I/O の並列化}{27} -\contentsline {section}{\numberline {7.3}I/O 専用 Thread の実装}{29} -\contentsline {chapter}{\numberline {第8章}ベンチマーク}{30} -\contentsline {section}{\numberline {8.1}実験環境}{30} -\contentsline {section}{\numberline {8.2}マルチコア}{31} -\contentsline {section}{\numberline {8.3}GPGPU}{33} -\contentsline {section}{\numberline {8.4}並列 I/O}{35} -\contentsline {chapter}{\numberline {第9章}既存のプログラミングフレームワークとの比較}{37} -\contentsline {section}{\numberline {9.1}OpenCL}{37} -\contentsline {section}{\numberline {9.2}CUDA}{38} -\contentsline {section}{\numberline {9.3}StarPU}{39} -\contentsline {chapter}{\numberline {第10章}結論}{41} -\contentsline {section}{\numberline {10.1}今後の課題}{42} -\contentsline {chapter}{謝辞}{43} -\contentsline {chapter}{参考文献}{44} -\contentsline {chapter}{発表文献}{45} +\contentsline {section}{\numberline {6.2}データ並列}{26} +\contentsline {chapter}{\numberline {第7章}並列処理向けI/O}{28} +\contentsline {section}{\numberline {7.1}mmap}{28} +\contentsline {section}{\numberline {7.2}Blocked Read による I/O の並列化}{29} +\contentsline {section}{\numberline {7.3}I/O 専用 Thread の実装}{31} +\contentsline {chapter}{\numberline {第8章}ベンチマーク}{32} +\contentsline {section}{\numberline {8.1}実験環境}{32} +\contentsline {section}{\numberline {8.2}マルチコア}{33} +\contentsline {section}{\numberline {8.3}GPGPU}{35} +\contentsline {section}{\numberline {8.4}並列 I/O}{37} +\contentsline {chapter}{\numberline {第9章}既存のプログラミングフレームワークとの比較}{39} +\contentsline {section}{\numberline {9.1}OpenCL}{39} +\contentsline {section}{\numberline {9.2}CUDA}{40} +\contentsline {section}{\numberline {9.3}StarPU}{41} +\contentsline {chapter}{\numberline {第10章}結論}{43} +\contentsline {section}{\numberline {10.1}今後の課題}{44} +\contentsline {chapter}{謝辞}{45} +\contentsline {chapter}{参考文献}{46} +\contentsline {chapter}{発表文献}{47}