view paper/chapter1.tex @ 77:f9b73e12a52f

fix
author Yuhi TOMARI <yuhi@cr.ie.u-ryukyu.ac.jp>
date Mon, 23 Feb 2015 19:12:19 +0900
parents 48db1f674a83
children
line wrap: on
line source

\chapter{既存のマルチプラットフォーム\\フレームワーク}
 マルチプラットフォームでプログラムを動作させる場合、そのアーキテクチャを意識する必要がある。
マルチプラットフォームにはマルチコア CPU 、 GPU や Cell といったヘテロジニアスマルチコアのような
様々な構成がある。

\section{GPU/Cell の Architecture}
\label{sec:shared_memory}
本研究では、 CPU の他に GPU 上でのプログラミング (GPGPU) にも対応する。

GPU(Graphics Processing Unit) は PC の画像処理を担当するユニットで、
レンダリングに特化したプロセッサが多く集まった構造を持つ。
一つ一つのプロセッサの構造は単純で、その機能は CPU に比べて限定的ではあるが
大量のデータを複数のプロセッサで並列処理することに長けている。
つまり、データ並列による実行を行った際、特に GPU の性能を充分に発揮できる。

GPGPU (General Purpose computing on Graphics Processing Units) とは、
 GPU の高い演算能力を画像処理ではなく汎用計算に使用することである。

計算機にはメモリ空間が別の計算機と、共有メモリ(Shared Memory)な計算機がある。
GPU のメモリ空間(図:\ref{fig:gpuarch})はマルチコア CPU (図:\ref{fig:cpuarch})と違い、
共有メモリ(shared mermoy)でないので Host と Device 間で Data の共有ができない。
そのためマルチプラットフォーム環境に対応したフレームワークには、
Device と Host 間でデータの転送を行う API 備わっている。
しかし、異なる Device 間でデータの転送を行うとネックになる。
そのためデータの入出力を行う回数を減らす、入出力の処理をパイプライン処理にするなどの工夫が必要になる。

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.4]{./images/gpu_arch.pdf}
  \end{center}
  \caption{GPU Architecture}
  \label{fig:gpuarch}
\end{figure}

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.8]{./images/cpu_arch.pdf}
  \end{center}
  \caption{CPU Architecture}
  \label{fig:cpuarch}
\end{figure}

Shared Memory でないプロセッサとして、Cell が挙げられる\cite{cell}。

Cell は1基の制御系プロセッサコア PPE ( PowerPC Processer Element ) と
8基の演算系プロセッサコア SPE ( Synergistic Processer Element ) で構成される。
各プロセッサコアはEIB (Element Interconnect Bus ) と呼ばれる高速なバスで接続されている。
また、 EIB はメインメモリや外部入出力デバイスと接続されており、
各プロセッサコアは EIB を経由してデータアクセスを行う。
PPE、SPE、メインメモリ、EIB の構成図を図:\ref{fig:cell_arch}に示す。
\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.8]{./images/cell_arch.pdf}
  \end{center}
  \caption{Cell Architecture}
  \label{fig:cell_arch}
\end{figure}

\newpage
%--------
% OpenCL
%--------

\section{OpenCL}
OpenCL とは、 Khronos Group の提供するマルチコア CPU と GPU といった、
ヘテロジニアス環境を利用した並列計算を支援するフレームワークである\cite{opencl}。

OpenCL では演算用プロセッサ側を Device 、制御用デバイス側を Host として定義する。
また、 Device 上で動作するプログラムの事を kernel と呼ぶ。

OpenCL では、デバイスの操作に Command Queue を使用する。
Command Queue は Device に命令を送るための仕組みである。
Command Queue は clCreateCommandQueue という OpenCL API で作成され、
Command Queue が所属するコンテキストや実行対象となる Device を指定する。

kernel の実行、input data への書き込み、 output data の読み込みといった
メモリ操作はこの Command Queue を通して行われる。

OpenCL には主に2つの仕様がある。

\begin{itemize}
\item OpenCL C言語
\item OpenCL Runtime API
\end{itemize}

OpenCL C は演算用プロセッサ上で動作する、 C 言語を拡張したプログラミング言語である。
一方で OpenCL Runtime API は OpenCL C で記述した kernel を Queuing するために Host が利用する API である。

Host では主に Data を input/output するメモリ資源の確保を行う。
OpenCL は host 側で memory buffer を作成してメモリのコピーを行う。
これらの処理や Task は Command Queue に enqueue することで実行される。


%------
% CUDA
%------
\section{CUDA}
CUDA とは、半導体メーカーNVIDIA社が提供するGPUコンピューティング向けの総合開発環境である\cite{cuda}。

CUDA も OpenCL と同様、演算用プロセッサ (GPU) を Device 、制御用デバイス側を Host として定義する。
また、 Device 上で動作するプログラムの事も kernel と呼ぶ。

OpenCL における Command と CommandQueue に対応するものとして、 CUDA には Operation と Stream がある。
Stream は Host 側で発行された Operation を一連の動作として Device で実行する。
Operation は発行された順序で実行されることが保証されている。
更に、異なる Stream に発行された Operation も依存関係が存在しない場合、Operationは並列に実行される。
更に依存関係が存在しない、異なる Stream に発行された Operation は並列に実行される。

CUDAには主に3つの仕様がある。

\begin{itemize}
\item CUDA C
\item CUDA Runtime API
\item CUDA Driver API
\end{itemize}
CUDA C は GPU 上で動作する、C 言語を拡張したプログラミング言語である。
CUDA Runtime API も CUDA Driver API も CUDA C で記述した Kernel を Queueing するために
 Host が利用するAPIである。
Driver API は Runtime APIに比べ、プログラマが管理しなければならないリソースが多くなる代わり、
より柔軟な処理を行う事ができる。

Stream は cuStreamCreate という Driver API で生成される。
引数に Stream を指定しない API は全て host 側をブロックする同期的な処理となる。
複数の Stream を同時に走らせ、 Operation を並列に実行するためには非同期的な処理を行う API を利用する必要がある。

\section{StarPU}
StarPUはフランス国立情報学自動制御研究所 (INRIA) の StarPU 開発チームの提供する、
ヘテロジニアス環境向けのフレームワークである\cite{starpu}。
 GPU の制御に OpenCL と CUDA を用いており、どちらかを選択することで GPU 上で実行することができる。

 OpenCL と CUDA における実行の単位は kernel だったが、 StarPU では実行の単位を Task と定義している。

 StarPU では Task を制御するためにcodeletと呼ばれる構造体を使う。
 codelet を Task 生成時にポインタ渡しすることで、
 演算を行うリソースや実行する関数等を指定することができる。
 CPU と GPU で並列に実行する例をソースコード:\ref{src:codelet}に示す。

\begin{lstlisting}[frame=lrbt,label=src:codelet,caption=codeletの例,numbers=left]
starpu_codelet codelet = {
    .where     = STARPU_CPU|STARPU_CUDA,
    .cpu_func  = cpu_function,
    .cuda_func = cuda_function,
};
\end{lstlisting}

\section{Cell Broadband Engine}
Cell Broadband Engine は、
ソニー・コンピュータエンタテイメント、ソニー、IBM 、東芝によって開発されたプロセッサである。
Cell は PPE と SPE によって構成されており、これらは OpenCL や CUDA で言うところの Device にあたる。
PPE は Cell Broadband Engine のメインプロセッサで、
複数の SPE をコアプロセッサとして使用できる汎用プロセッサである。
メインメモリや外部デバイスへの入出力、SPE を制御する役割を担っている。

SPE は PPE によって制御される演算系のプロセッサである。
\ref{sec:shared_memory}節でも述べた通り、 SPE からメインメモリへ直接アクセスすることはできず、
 DMA (Direct Memory Access) 転送によってアクセスを行う。
DMA 転送とは CPU を介さずに周辺装置とメモリとの間でデータ転送を行う事で、
SPE が持っているコントローラが DMA Controller と通信することで行われる。手順としては以下のようになる。

\begin{enumerate}
  \item SPE で起動しているプログラムが、コントローラに対して DMA 転送命令を発行
  \item SPE の持つコントローラが DMA Controller を介して DMA 転送を開始。
    この間 SPE で起動しているプログラムは停止しない
  \item 転送が開始したら、SPE プログラムが転送の完了を待つ

\end{enumerate}

Cell の PPE には主に2つの仕様がある。

OpenCL には主に2つの仕様がある。

\begin{itemize}
\item SPU 拡張 C/C++
\item libSPE2
\end{itemize}

SPE 上で動作する、拡張された C/C++ の言語を用いる。
通常の C/C++ 言語との違いは DMA 転送、SIMD 演算(加算、減算、乗算)に対応していることが挙げられる。
一方で libSPE2 は PPE が SPE を制御するためのライブラリ群である。