annotate paper/osmesa.tex @ 5:d655863e53b0

*** empty log message ***
author akira
date Sat, 16 Feb 2008 12:37:47 +0900
parents 3f96fdc6d522
children 15383f05a316
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
1 \chapter{OSMesa}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
2 PlayStaiton3では以前我々が扱っていたPlay Station2と違ってGPUに直接アクセスすることができない。しかし、ps3fbは扱うことができる。そこで我々は描画にSDLおよびOpenGLを用いて開発を行うことにした。SDLのfbcon driverにはOpenGLがないため、CPUはそれなりに早いが、グラフィックス性能はフレームバッファしかないという環境でよく用いられるOSMesaを使用し、移植開発を行った。
5
d655863e53b0 *** empty log message ***
akira
parents: 3
diff changeset
3 PPUのみで動作するOSMesaとSDLを用いて作ったSuper Dandy(s-dandy)はある程度のスピードでうごくが、そのスピードでは不十分である。そこでOSMesaを今回の実験材料として用い、OSMesaの一部の機能をSPUを使用して高速化を行った。
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
4 \section{OSMesaの機能}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
5 \subsection{ポリゴンの回転・拡大・縮小}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
6 まず最初にOSMesaはポリゴンと呼ばれる三角形の各頂点座標を入力値として利用している。図\ref{fig:texture}の左の図がポリゴンに相当する物となる。ポリゴンの頂点座標から次の動作の命令を汲み取った上で、動作に伴う行列演算を行う。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
7 \subsection{spanの生成}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
8 動作に伴う演算から得られたポリゴン情報はいったんspanという構造体に変換される。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
9 図\ref{fig:texture}で線が引かれている部分がspanである。ポリゴン情報からy座標別に情報を分割し、図\ref{fig:texture}ではy=15のところのspanを示している。左端の点のx、y、z座標とRGB$\alpha$、右端のx、zとRGB$\alpha$から構成される。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
10 \subsection{テクスチャの生成とマッピング}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
11 テクスチャの読み込みはSDL\_imageを利用して行う。IMG\_Loadという関数でテクスチャの情報をメモリに格納し、そのテクスチャのx、yをO~1で扱う。図\ref{fig:texture}ではy=15のラインで、左端がテクスチャの値を(0.3,0.5)、右端が(0.5,0.7)という値で保持している。それは右のテクスチャの線が引かれた部分に相当する。つまり、y=15のラインはテクスチャの線の部分がマッピングされることになる。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
12 \subsection{zバッファ}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
13 OSMesaは描画を行う際、zバッファというメモリ領域を確保している。zバッファは描画する画面の大きさのメモリ空間を持ち、それぞれのx、y座標に対応するzの値を保持している。そのx、y座標が描画する際、zバッファにzの値を書き込んでおく。そうすると、今度同じx、y座標に描画する際、zの値をみてカメラに向かって、今書き込むもうとしているものがもとあるものより、手前にあるのか、おくにあるのかを判断する。手前にある場合はzバッファを更新するとともにそのx、y座標のRGB$\alpha$も更新し、おくにある場合はなにもしない。そうすることにより3Dをうまく表示している。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
14
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
15 %OSMesaはポリゴンと呼ばれる三角形の各頂点座標からy座標ごとにspanと呼ばれる構造体を生成し、そのspanのZの値をみながらいったんメモリに書き出し、それをまとめてframe bufferに書き出す。\\
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
16 %テクスチャを使用する場合は、各頂点に対応したテクスチャ座標を持っており、その値からテクスチャのどのxy座標のRGBがその点に対応するかを計算してRGBを書き込むようなシステムになっている。図\ref{fig:texture}では左にポリゴンが書かれており、各頂点にはxyz座標とテクスチャに対応する相対比がある。その相対比からテクスチャのどの部分がポリゴンに対応しているかがわかる。それによりテクスチャの黒い線が左のポリゴン上の1行の線にマッピングされる。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
17 \begin{figure}[htb]
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
18 \begin{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
19 \includegraphics[width=17cm]{./fig/texture2.eps}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
20 \end{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
21 \caption{ポリゴンとテクスチャ}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
22 \label{fig:texture}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
23 \end{figure}
5
d655863e53b0 *** empty log message ***
akira
parents: 3
diff changeset
24 %\subsection{ダブルバッファリング}
d655863e53b0 *** empty log message ***
akira
parents: 3
diff changeset
25 %ダブルバッファリングとは1画面が描画している間に次に描画する画像を裏でいったん生成しておき、描画する画像を切り替える手法である。画面を一気に切り替えるため、ちらつきがなくなる。
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
26 \section{高速化する部分}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
27 OSMesaの機能を分割し、SPUにTaskとして割り振る方法はいくつか考えることができる。我々は最初テクスチャのついてないオブジェクトを対象とし、spanをzバッファでみながら描画していく方法を高速化した。高速化する部分のコードは以下のようになっている。\\
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
28 \input{src/render_span_macro.c}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
29 最初の3行が実際のコードに記述された物になる。しかし、OSMesaはマクロを多用して実装されている。このマクロを展開したコードをいかに示す。
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
30 \input{src/render_span.c}
76144c47b4fc Initial revision
akira
parents:
diff changeset
31 コードを説明する前にコードで用いられているspanについて先に説明しておく。spanとは次のような構成からなっている。\\
76144c47b4fc Initial revision
akira
parents:
diff changeset
32 \begin{table}[htb]
76144c47b4fc Initial revision
akira
parents:
diff changeset
33 \begin{center}
76144c47b4fc Initial revision
akira
parents:
diff changeset
34 \begin{tabular}{|c|l|}
76144c47b4fc Initial revision
akira
parents:
diff changeset
35 \hline
76144c47b4fc Initial revision
akira
parents:
diff changeset
36 x、y、z & 生成されるspanの左端のx、y、z座標 \\ \hline
76144c47b4fc Initial revision
akira
parents:
diff changeset
37 red、green、blue、alpha & 生成されるspanの左端のRGB$\alpha$情報 \\ \hline
76144c47b4fc Initial revision
akira
parents:
diff changeset
38 end & 生成されるspanの長さ \\
76144c47b4fc Initial revision
akira
parents:
diff changeset
39 & (x、y)からこの長さの分だけ描画される\\ \hline
76144c47b4fc Initial revision
akira
parents:
diff changeset
40 zStep & 生成されるspanのxが1増加したときの\\
76144c47b4fc Initial revision
akira
parents:
diff changeset
41 &zの増加量 \\ \hline
76144c47b4fc Initial revision
akira
parents:
diff changeset
42 redStep,greenStep,blueStep,alphaStep & 生成されるspanのxが1増加したときの\\
76144c47b4fc Initial revision
akira
parents:
diff changeset
43 &RGB$\alpha$の増加量 \\ \hline
76144c47b4fc Initial revision
akira
parents:
diff changeset
44 \end{tabular}
76144c47b4fc Initial revision
akira
parents:
diff changeset
45 \caption{SPANの情報}
76144c47b4fc Initial revision
akira
parents:
diff changeset
46 \label{table:span}
76144c47b4fc Initial revision
akira
parents:
diff changeset
47 \end{center}
76144c47b4fc Initial revision
akira
parents:
diff changeset
48 \end{table}
76144c47b4fc Initial revision
akira
parents:
diff changeset
49
76144c47b4fc Initial revision
akira
parents:
diff changeset
50 \begin{figure}[htb]
76144c47b4fc Initial revision
akira
parents:
diff changeset
51 \begin{center}
76144c47b4fc Initial revision
akira
parents:
diff changeset
52 \includegraphics{./fig/span_data.eps}
76144c47b4fc Initial revision
akira
parents:
diff changeset
53 \end{center}
76144c47b4fc Initial revision
akira
parents:
diff changeset
54 \caption{span data}
76144c47b4fc Initial revision
akira
parents:
diff changeset
55 \label{fig:span_data}
76144c47b4fc Initial revision
akira
parents:
diff changeset
56 \end{figure}
76144c47b4fc Initial revision
akira
parents:
diff changeset
57 図\ref{fig:span_data}で、spanの構造体を表している。同じy座標に対しての描画する一番左端のx、y、z座標とその位置に対するRGB$\alpha$が与えられ、その位置から描画される長さ(end)、xが1増加したときの各情報の増加量がこのコードに達するまでに計算されてきた。\\
76144c47b4fc Initial revision
akira
parents:
diff changeset
58 つまりこのコードでは、まず与えられたspanのx、y座標からzバッファのアドレ
76144c47b4fc Initial revision
akira
parents:
diff changeset
59 スを計算する。次にそのx、y座標からzが計算され今まで計算されてきたzとの比
76144c47b4fc Initial revision
akira
parents:
diff changeset
60 較を行う。この比較によって今まで与えられたポリゴン情報と今与えられたポリ
76144c47b4fc Initial revision
akira
parents:
diff changeset
61 ゴン情報のどちらがカメラからみて手前にあるかを計算する。もし、対応する
76144c47b4fc Initial revision
akira
parents:
diff changeset
62 spanが手前にある場合はそのx、y座標にRGB$\alpha$を更新し、zバッファを更新
76144c47b4fc Initial revision
akira
parents:
diff changeset
63 しておく。こうすることにより、今までのspanからどれが一番手前の情報化を保
76144c47b4fc Initial revision
akira
parents:
diff changeset
64 持しておく。その後で、x座標を1ずらす際にRGB$\alpha$とzの更新が行われる。
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
65 それをend(長さ)分繰り返しておく。それが1画面分終了したら、描画にうつる。
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
66
76144c47b4fc Initial revision
akira
parents:
diff changeset
67
76144c47b4fc Initial revision
akira
parents:
diff changeset
68
76144c47b4fc Initial revision
akira
parents:
diff changeset
69 \section{実装}
76144c47b4fc Initial revision
akira
parents:
diff changeset
70 zバッファは1ピクセルのx座標、y座標に対してのz情報である。それを各SPUで大
76144c47b4fc Initial revision
akira
parents:
diff changeset
71 量(現在の日本のテレビ規格だと1920×1080)に持つと、
76144c47b4fc Initial revision
akira
parents:
diff changeset
72 $1920\times1080\times4=8294400$byteのメモリ量が必要となりモリが不足する。また、同じx座標、y座標のzバッファに対し、別のSPUで処理すると、同じ1ピクセルを別のSPUが描画することになるため、単純に分割することはできない。\\
76144c47b4fc Initial revision
akira
parents:
diff changeset
73 そこで我々はspanを生成し、描画するルーチンからy座標ごとにspanをソートして持っておく。各SPUには、y座標が一致しているspanが送信される。y座標が一致しているspanが複数のSPUに対して送信されることはない。\\
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
74 例えば、同じy座標のspanが複数のポリゴンから生成されたとする。そのspanはすべて同じリストに追加される。y座標毎にspanのリストを一定数とり、そのリストを更にDMA量にあわせてリスト化する。ここではy座標ごとのspanのリストをspanlistとする。\\
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
75 そうすることにより、各SPUは1ライン分のフレームバッファだけを持つだけでよ
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
76 く、メモリの問題も解決する。まず最初に高速化するルーチンのところにきた
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
77 span情報をy座標ごとに生成する。(図\ref{fig:y_list})\\
76144c47b4fc Initial revision
akira
parents:
diff changeset
78 \begin{figure}[htb]
76144c47b4fc Initial revision
akira
parents:
diff changeset
79 \begin{center}
76144c47b4fc Initial revision
akira
parents:
diff changeset
80 \includegraphics[height=5cm]{./fig/y_list.eps}
76144c47b4fc Initial revision
akira
parents:
diff changeset
81 \end{center}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
82 \caption{spanlist}
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
83 \label{fig:y_list}
76144c47b4fc Initial revision
akira
parents:
diff changeset
84 \end{figure}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
85 しかし、y座標ごとに生成されたspanを使用するSPUの数に単純に分割するだけではあまり効率が良くない。そこで、y座標ごとに生成されたspanのリストを更にまとめたうえで、リスト化する。ここでは64個のy座標ごとのspanのリストをまとめている。それをSPUの数分つくり、図\ref{fig:span_list}のようなリストにする。ここではSPUが受け取る最初のリストをspanpacklistと呼ぶことにする。ここで64個のy座標ごとのリストを作るのはアドレスの転送回数を減らすことにある。\\
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
86 \begin{figure}[htb]
76144c47b4fc Initial revision
akira
parents:
diff changeset
87 \begin{center}
76144c47b4fc Initial revision
akira
parents:
diff changeset
88 \includegraphics[height=7cm]{./fig/span_list.eps}
76144c47b4fc Initial revision
akira
parents:
diff changeset
89 \end{center}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
90 \caption{spanpacklist}
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
91 \label{fig:span_list}
76144c47b4fc Initial revision
akira
parents:
diff changeset
92 \end{figure}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
93 そこからy座標ごとのspanのリストをDMAでとってくる。SPUが実際に持つspanは同じy座標のみで、zバッファは1行分だけでよい。
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
94 \subsection{ダブルバッファリング}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
95 spanを生成して、描画している間にもPPUは動くことができる。今回の実装ではダブルバッファを用いている。つまり、PPUではSPUが描画している間、次のSpanを生成し、SPUに送るSpanのリストを作っている。SPUも同時にspanを読み込むときにダブルバッファで読み込んでいる。(図\ref{fig:parallel})\\
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
96 \begin{figure}[htb]
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
97 \begin{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
98 \includegraphics{./fig/parallel.eps}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
99 \end{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
100 \caption{parallel}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
101 \label{fig:parallel}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
102 \end{figure}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
103 そうすることにより、PPUとSPUが効率よく使われ更なる高速化が得られている。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
104 \subsection{パイプライン}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
105 CellはDMAの機能を持っているので、パイプライン的な処理が可能となる。基本的な要素
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
106 としてRead、Exec、Writeから構成できる。(図\ref{fig:pipeline})\\
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
107 \begin{figure}[htb]
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
108 \begin{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
109 \includegraphics{./fig/pipeline.eps}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
110 \end{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
111 \caption{pipeline実行}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
112 \label{fig:pipeline}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
113 \end{figure}
2
76144c47b4fc Initial revision
akira
parents:
diff changeset
114 \subsection{SPUプログラム}
3
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
115 spanpacklistとダブルバッファを用いてSPUのプログラムを記述すると以下のようになる。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
116 \input{src/spe_main.c}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
117
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
118 ほとんどの部分がダブルバッファのDMA制御を行っている。計算を行っている部分はPPUのみで行われていたコードにDMAのダブルバッファを考慮したものである。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
119 \input{src/calc.c}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
120 ダブルバッファは入力用の構造体を二つ、出力用の構造体二つで構成されている。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
121 \section{評価}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
122 \subsection{実行速度比較}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
123 単純にSDLとOSMesaを用いたものとSPUを使ったOSMesaを使用したものとを比較した。例題としてはSDLに付属しているtestglというCubeが回転しているテクスチャがはられていないものを利用した。実行時間はSDLに標準で出ろくされるFPSを用いる。FPSは1秒間に何枚の画像が表示されているかを表す物である。計測結果は以下のようになる(表\ref{table:exectime})。これはCellの上ではやはりSPUをなるべく使った方が実行速度ははやくなるということを示していると同時によりOSMesaを細分化し、できるだけSPUをつかうよな設計をすると、よりはやくなる可能性を示す物であった。OSMesaがメジャーアップデートされると、それにOSMesaの最適化が加わり、更に1.8倍早くなった。
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
124 \begin{table}[htb]
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
125 \begin{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
126 \begin{tabular}{|l|c|}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
127 \hline
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
128 SDL(1.2)+OSMesa(6.5.2) & 18FPS \\ \hline
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
129 SDL(1.2)+OSMesa(6.5.2) with SPU & 24FPS \\ \hline
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
130 SDL(1.2.13)+OSMesa(7.0.2) with SPU & 43FPS \\ \hline
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
131 \end{tabular}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
132 \end{center}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
133 \caption{OSMesaの実行時間比較}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
134 \label{table:exectime}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
135 \end{table}
3f96fdc6d522 *** empty log message ***
akira
parents: 2
diff changeset
136 \subsection{総合評価}
5
d655863e53b0 *** empty log message ***
akira
parents: 3
diff changeset
137 実行速度比較から高速化には成功したが、巨大なマクロによるプログラム記述やコピーの多用、巨大な構造体などがあり、遅くなっている要因がわかった。さらに高速化を行うためにはテクスチャの計算などを並列に行う必要があった。しかし、テクスチャ処理がメインメモリ依存で記述されているため、拡張がとても難しく、OSMesaは時代遅れなライブラリ群といえる。また、OSMesaの機能などをSPUに分割すると、OSMesaよりもわかりやすいという教育効果を得ることができる。