cell challenge 2009 参加記

51
Cell Challenge 2009参戦記 @Kansai.pm#11 吉田 悠一

Upload: yuichi-yoshida

Post on 18-Jul-2015

3.087 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Cell Challenge 2009 参加記

Cell Challenge 2009参戦記@Kansai.pm#11

吉田 悠一

Page 2: Cell Challenge 2009 参加記

自己紹介

• 修士2年@京都大学大学院情報学研究科– 専門は理論計算機科学: PNPを証明したい的分野

• エンジニア@Preferred Infrastructure (PFI)

• OSS: Anthy(かな漢字変換エンジン)など

• プログラミングコンテスト: ICPC世界大会(2007,2008)

• はてなブックマークの関連エントリ機能の実装。

• Web: http://lab2.kuis.kyoto-u.ac.jp/~yyoshida/

• Blog: http://mono.kmc.gr.jp/~oxy/d/

Page 3: Cell Challenge 2009 参加記

Cell Challengeとは

• マルチコア環境を効率的に利用するための並列化プログラミングでは,スケーラビリティや並行タスクの発見,生成,スレッド化をいかに行うかが課題。– (http://www.hpcc.jp/sacsis/2009/cell/ から引用)

• PS3に搭載されているCellプロセッサを使って、与えられた問題をとにかく速く解くプログラムを作る。

– 先進的計算基盤システムシンポジウム(SACSIS)の併設企画

Page 4: Cell Challenge 2009 参加記

経緯

• 2008年秋頃(?):

– 東工大の岡本先生(実行委員)に参加しないかと誘われる。

– Cellとかめんどそう

• 2008年12月:

– 問題発表: 編集距離!

– 桜庭さん(東大,PFI)がこれ速く解けるんじゃねと興味津津

– 桜庭さんに実装を全て任せることにして口出し担当で参加。

– チーム名どうするかね。

Page 5: Cell Challenge 2009 参加記

ネーミング

• ハンドルネームは合体させづらい(chunとoxy)。– choxy, oxyn…ぴんとこない。

• Skypeで相談するもなかなか決まらない。

• そこで目についたのが弊社社長のSkype上での名前

Page 6: Cell Challenge 2009 参加記

(≧ω≦)に決定

Page 7: Cell Challenge 2009 参加記

経緯

• 2009年1月~:

– Cell the Hack

– メルセンヌツイスター法(乱数生成の手法)をCellで高速化

– Blogや2chに大量に情報が流れる

– こそこそと情報収集

• 2009年2月:

– Cell Challenge 2009予選終了

– 首位!

Page 8: Cell Challenge 2009 参加記

出典: http://www.hpcc.jp/sacsis/2009/cell/kiteiyosen2009.htm

Page 9: Cell Challenge 2009 参加記

経緯

• 2009年3月21日:

– 本選終了

– 結果待ち

– 勝てると良いなぁ。

• 2009年3月22日:

– 満を持してKansai.pmで発表

Page 10: Cell Challenge 2009 参加記

何故Kansai.pmでCell Challengeか

• ポジティブな理由:

– 高度なプログラムを作るには、いついかなる場合も、

アルゴリズムとアーキテクチャに対する深い造詣が必要。

– Cellプロセッサでのプログラミングはこれらを学ぶのにとても良い。

• ネガティブな理由:

– Perl読めない($$@@$@$@##@$@)

– Webフレームワーク知らない

• 是非、今日の話をみなさんの分野でも活用させてください。

Page 11: Cell Challenge 2009 参加記

今年の課題:編集距離

Page 12: Cell Challenge 2009 参加記

既定課題: 編集距離

• 二つの文字列どうしの近さの測り方の一つ。

• 文字列Aを文字列Bに変形するのに必要な操作の最小回数。

• 操作は以下の3種類– 文字を挿入

– 文字を削除

– 文字を置換

Page 13: Cell Challenge 2009 参加記

編集距離の計算の例

• A=weight, B=write

1. weighte (挿入:e)

2. wrighte (置換:e → r)

3. wrihte (削除:g)

4. write (削除:h)

• 3回以下の操作ではAをBに変形できないのでAとBの編集距離は4。

Page 14: Cell Challenge 2009 参加記

問題設定

• 二つの文字列A, Bが与えられる。

• AとBの間の編集距離をCellを使って出来るだけ速く求めなさい。

• 制約:– |A|,|B|220-128, |A||B|234

– |A|,|B|は128で割り切れる。

– 文字は1~255の255種類。

• まず以下を説明– Cellとはどんなプロセッサ?

– 編集距離を求める典型的な手法

Page 15: Cell Challenge 2009 参加記

Cellの構造

MFC

SXU

LS

SPU

SPE

MFC

SXU

LS

SPU

MFC

SXU

LS

SPU

MFC

SXU

LS

SPU

MFC

SXU

LS

SPU

MFC

SXU

LS

SPU

MFC

SXU

LS

SPU

MFC

SXU

LS

SPU

EIB

PXUL1

PPUPPE

L2

IO メモリ

Page 16: Cell Challenge 2009 参加記

Cellの構造

• 周波数: 3.2GHz

• PPE(PowerPC Processor Element):

– L1: 32KB, L2: 512KB

– VMX

– 全体の動作の管理に使うことが多い。

• SPE(Synergistic Processor Element):

– LS: 256KB

– 128bitのレジスタが128個

– SIMD

– 重たい計算に使うことが多い。

Page 17: Cell Challenge 2009 参加記

編集距離の動的計画法(DP)による解法

• 編集距離はO(nm)時間で計算出来る。(n=|A|,m=|B|)

• T[i,j]=Aの前i文字とBの前j文字の間の編集距離

T 0 1 2 3 4 5 6

w e i g h t

0 0 1 2 3 4 5 6

1 w 1 0 1 2 3 4 5

2 r 2 1 1 2 3 4 5

3 i 3 2 2 1 2 3 4

4 t 4 3 3 2 2 3 3

5 e 5 4 3 3 3 3 4

i T[i,0]=i

j T[0,j]=j

T[i,j]=min(

T[i-1,j]+1,

T[i,j-1]+1,

T[i-1,j-1]+(A[i]B[j]))

挿入

削除

置換

Page 18: Cell Challenge 2009 参加記

サンプルプログラムと(≧ω≦)のプログラム

• Cell Challengeの運営側が公開しているプログラム– 前述のDP+自然な7並列

– |A|=217, |B|=217のデータで43秒ぐらい

• (≧ω≦)のプログラム– 予選: 同データで0.2秒ぐらい

– 本選: 同データで0.14秒ぐらい

• 約300倍の高速化!

Page 19: Cell Challenge 2009 参加記

(≧ω≦)の手法

• 基本的な考え方は前述の動的計画法で良い。

• これをCellの特徴を生かして高速化していく。

1. アルゴリズム的な改善

2. SPE一個単位での高速化– SIMD, 128ビットのレジスタ

– パイプライン, スーパスカラ, 分岐予測

– ページング

3. SPE複数個単位での高速化– メモリ転送, SPE間の同期

– SPEへのタスク配分

Page 20: Cell Challenge 2009 参加記

アルゴリズム的な改善

Page 21: Cell Challenge 2009 参加記

理論屋の考え方

• SPEがいくら7個あるとはいっても、せいぜい7倍じゃないか。

• そんな7倍程度を気にする前にアルゴリズムを改善して100倍速ぐらいにしとくべき。

• 実際、128bitのレジスタを使うと、先ほどのDP表の128要素を同時に持てる!

Page 22: Cell Challenge 2009 参加記

次の数スライドが分からなくても

それは自然なことです。

Page 23: Cell Challenge 2009 参加記

ビット並列化[H03]

• DP表Tの隣り合った要素の差は高々1。

• PMj, D0j,HPj,HNj,VPj,VNj{0,1}n, n=|A|を以下の様に定義。

• PMj[i] = 1 iff A[i] = B[j]

• D0j[i] = 1 iff T[i,j] = T[i-1,j-1]

• VPj[i] = 1 iff T[i,j] - T[i-1,j] = 1

• VNj[i] = 1 iff T[i,j] - T[i-1,j] = -1

• HPj[i] = 1 iff T[i,j] - T[i,j-1] = 1

• HNj[i] = 1 iff T[i,j] - T[i,j-1] = -1

1 2

w e

0 1 2

1 w 0 1

2 r 1 1

3 i 2 2

4 t 3 3

5 e 4 3

PM2=

0

0

0

0

1

D02=

1

0

0

0

0

VP2=

0

0

1

1

0

VN2=

1

0

0

0

0

HP2=

1

0

0

0

0

HN2=

0

0

0

0

1

Page 24: Cell Challenge 2009 参加記

ビット並列化[H03]

• j列目のベクトルはj-1列目のベクトルから以下のように計算出来る。

• D0j=(((PMj&VPj-1)+VPj-1)&VPj-1)|PMj|VNj-1

• HPj=VNj-1|~(D0j|VPj-1)

• HNj=D0j&VPj-1

• VPj=(HNj<<1)|~(D0j|(HPj<<1)|1))

• VNj=D0j&((HPj<<1)|1)

– 各演算はbitwise

• AとBの編集距離=n+ VPj[n]- VNj[n]

0 1 2

w e

0 0 1 2

1 w 1 0 1

2 r 2 1 1

3 i 3 2 2

4 t 4 3 3

5 e 5 4 3

Page 25: Cell Challenge 2009 参加記

ビット並列化

• これらのベクトルを128bitのレジスタを使って計算する。

• CellにはSIMDが備わっているが高々4並列程度。それに比べてビット並列化は128並列!– SIMD: (例えば)128bitのレジスタを32bitのレジスタ*4と思って

32bitどうしの演算を同時に4つ実行する

• DP表Tの要素間には依存関係が有り並列化しにくいはず。

• それでも並列化できているのは、依存関係を足し算の繰り上がりという形で表現しているから。– D0j=(((PMj&VPj-1)+VPj-1)&VPj-1)|PMj|VNj-1

Page 26: Cell Challenge 2009 参加記

雑感

• 今回の問題はビット並列化しなければ他をどう頑張っても勝てないものと思われる。

• 217*217のデータで1秒の壁というものが2chで議論されていたが、ビット並列+7SPEによる並列を適当に実装すればそれだけで1秒ぐらいになる。

• しかしまだ0.14秒との間には7倍程度の差。

Page 27: Cell Challenge 2009 参加記

SPE一個単位での高速化

Page 28: Cell Challenge 2009 参加記

基礎知識: パイプライン

• 1命令を複数の工程に分けて実行する。

– スループットを向上。クロック数の向上。レイテンシは悪化する。 Cycle

1 2 3 4 5 6 7 8

命令1 IF ID EX WB

命令2 IF ID EX WB

命令3 IF ID EX WB

命令4 IF ID EX WB

命令5 IF ID EX WB

IF: 命令フェッチ, ID: 命令デコード, EX: 実行, WB: (レジスタへの)書き戻し

Page 29: Cell Challenge 2009 参加記

基礎知識: データ依存とデータハザード

• 命令が利用するデータ間に依存関係があると、前の命令が終わらないと後ろの命令が実行できない。

• cの値が確定するまでmul d c cが実行出来ない。

• 先ほど8サイクル5命令だったのが2命令に。

Cycle

1 2 3 4 5 6 7 8

add c a b IF ID EX WB

mul d c c --- --- --- IF ID EX WB

Page 30: Cell Challenge 2009 参加記

ハザードに対する対応策:ループアンローリング

c[0] = a[0]+b[0]; d[0] = c[0]*c[0];

c[1] = a[1]+b[1]; d[1] = c[1]*c[1];

c[2] = a[2]+b[2]; d[2] = c[2]*c[2];

c[3] = a[3]+b[3]; d[3] = c[3]*c[3];

c[0] = a[0]+b[0]; c[1] = a[1]+b[1];

c[2] = a[2]+b[2]; c[3] = a[3]+b[3];

d[0] = c[0]*c[0]; d[1] = c[1]*c[1];

d[2] = c[2]*c[2]; d[3] = c[3]*c[3];

for (i=0;i<4;++i) { c[i] = a[i]+b[i]; d[i] = c[i]*c[i]; } ハザード!

ループアンローリング

命令を並び替えることで、ハザードが緩和される

Page 31: Cell Challenge 2009 参加記

ループアンローリングの効用

• ループアンローリングは抜群に効く。

• データハザードが消えることで簡単に2、3倍の速度になる。

• 折角なのでデモ

Page 32: Cell Challenge 2009 参加記

ハザードに対する対応策: 投機実行

• 例: 128bit整数の加算

• Cellには128bit整数の加算命令は無い。

• 32bitの加算*4(SIMD)はあるので、これで模倣する。

• その際繰り上がりの処理が問題になる。– 下の桁の繰り上がりが上の桁に影響する。

– データ依存によりハザード発生。

• 途中で繰り上がりが発生するのとしないのを両方実行して、後で正しい方を選ぶようにすると速くなる(時もある)。– 依存関係を遅延評価する。

Page 33: Cell Challenge 2009 参加記

足し算のさらなる効率化

• 普通の実装だと128bitレジスタに128行1列分の情報をいれることになる。

• Cellには128bitの足し算が無いので、

32bitの足し算で模倣するしかなかった

• 32bitの足し算しかないなら、

それに合わせてレジスタの使い方も

変えればいいじゃない。

32

1

Page 34: Cell Challenge 2009 参加記

• つまりこういうこと。

• この管理法なら32bitの足し算*4が有れば良い。

• 結局これは実装していないが、

多分速くなる。

• 他のチームがこれやってないのを

願うばかり。

32

1

Page 35: Cell Challenge 2009 参加記

基礎知識: スーパースカラ

• Cellはパイプラインを二つ持っており、同時に二つの命令を発行出来る。– Evenパイプライン: 四則演算, ビット演算など

– Oddパイプライン: ロードストア, シフト, 分岐など

Cycle

1 2 3 4 5 6

Even命令1 IF ID EX WB

Odd命令1 IF ID EX WB

Even命令2 IF ID EX WB

Odd命令2 IF ID EX WB

Even命令3 IF ID EX WB

Odd命令3 IF ID EX WB

Page 36: Cell Challenge 2009 参加記

スーパスカラの活用

• Evenパイプライン用の命令ばかり使うと、Oddパイプラインが暇になる。– Evenパイプラインの処理を等価なOddパイプラインを使う処

理に変換することで高速化が望める。

• ビット並列化がビット演算ばかりするのに対し、Odd

パイプライン用の命令はバイト単位の演算ばかりなので、今回はあまり最適化できなかった。

Page 37: Cell Challenge 2009 参加記

SPE複数個単位での高速化

Page 38: Cell Challenge 2009 参加記

• SPEの数は7個なので、どんなに頑張っても7倍速にしかならない。

• けれども適当に実装すると7倍速にさえならないので、7倍に近づける努力をする必要がある。

Page 39: Cell Challenge 2009 参加記

並列化の方法

• T[i,j]を128c*128のブロックに分割する。

• 各ブロック内の値はその上と左の境界の情報があれば計算することが出来る。

• 各SPEに128c行を担当させ、ブロックの計算が終わるたびに、下の行を担当しているSPEにその情報を渡す。

• PPEはマネージャとして使用。

SPE1

SPE2

SPE3

SPE4

SPE1

128c

128

Page 40: Cell Challenge 2009 参加記

SPEへのタスク割り当て

• 各SPEに128c行割り当てることにしたのは良いが、cをいくらにする?

• cが少ないと– 初期化やらSPE間のデータのやりとりやらが増える。

– ループアンローリングの効果が減る。

• cが大きいと– レジスタが足りなくなる。

– コンパイル時間が長くなる。

• 実験の結果cは16ぐらいが宜しい。

Page 41: Cell Challenge 2009 参加記

• 常にc=16で良いか?: NO

• 例えば行数が(128*16)*8とする。

• SPE7個で(128*16)*7行をまず処理。

• 残った128*16行をSPE1個で処理。残りの6個ぽかーん。

• 最後まで7個のSPEが同時に動いていてほしい!

Page 42: Cell Challenge 2009 参加記

有名事実

• x,n: 任意の正整数

sum=0

for (i=0;i<n;++i)

sum += (x+i)/n

// sum == x

• 例: x=29, n=5 ⇒ (x+i)/n=5,6,6,6,6

• これを使って次のSPEに何行割り当てるかを決める。

Page 43: Cell Challenge 2009 参加記

• |A|=128x行とする。

• nに対する制約は二つ– nは7の倍数⇒ n=(適当な数)*7

– x/nの切り上げは高々16 ⇒ n=(x+16-1)/16

• n=(x+16*7-1)/(16*7)*7とすればよい

for (i=0;i<n;++i)

(x+i)/n *128行を次のSPEに割り当て

Page 44: Cell Challenge 2009 参加記

基礎知識: ページング

• プログラムから見えるメモリのアドレス(仮想アドレス)

は、ハードウェア的なメモリ上の位置を表しているわけではない。

• ページング: 仮想アドレスとメモリの実際の位置の対応づけ。

• まだページングされていない仮想アドレスにアクセスすると、ページフォールトが発生し、ページングが行われる。

Page 45: Cell Challenge 2009 参加記

ページフォールトに対する対応策

• SPE側でページングされていないメモリにアクセスすると、何故かものすごく時間がかかる模様。– 100万~1000万クロック程?

• PPE側で事前にメモリを初期化することでページフォールトを予め起こしておくとよい。

• 具体的には一回適当にアクセスするだけ。

• デモ。

Page 46: Cell Challenge 2009 参加記

まとめ

• アルゴリズム的な改善は一番大事– ビット並列化

• そもそも必要な計算の量が大きく変わる。

• 有名問題なら本やら論文やらを当たればいくらでも知識は得られる。

• その他の最適化は基本的には同じ計算をどうやってコンピュータに速く解かせるかという問題。

• コンピュータそのものに対する知識無しに高速化出来るわけが無い。– パイプライン、ページング、キャッシュ、SIMD…

Page 47: Cell Challenge 2009 参加記

まとめ

• その後の最適化は問題依存のパズル。– レジスタの使い方(32bit*4)とか

– SPEへのタスク割り当てとか

• この辺の頭の使い方はコードゴルフとかと同じ種類のものな気がする。

• 流行のものを学ぶのも良いけど、そうでないところにも面白い話題は一杯転がっていますよ。

Page 48: Cell Challenge 2009 参加記

参考文献

• Cell Speed Challenge 2009

http://www.hpcc.jp/sacsis/2009/cell/

• Multicore Programming Primer: PS3 Cell Programming

http://www.cag.csail.mit.edu/ps3/index.shtml

• Heikki Hyyrö. A Bit-Vector Algorithm for Computing

Levenshtein and Damerau Edit Distances. Proceedings

of the Prague Stringology Conference, 29 – 32, 2003.

Page 49: Cell Challenge 2009 参加記

入力について

Page 50: Cell Challenge 2009 参加記

予選問題

• 予選の数日後に予選問題は公開された(本選はまだ)。

• 色々なサイズの問題が5個

• Q1:

• Q2:

• Q3:

• Q4:

• Q5:

• 予選の結果を眺めると傾向が見える。

Page 51: Cell Challenge 2009 参加記

• 明らかに真面目に計算しなくても良い問題が含まれている。

• Q1: 二つの文字列が同一

• Q2: 片方の文字列が片方の文字列を含んでいる– abcdとbdみたいな。

• Q3: ランダム?(気づいていないだけか)

• Q4: 片方が片方の接頭辞:

– abcdとabみたいな。

• Q5: 共通接頭辞を取り除くと使う文字がかぶっていない。– aaabcdとaaaxyzみたいな。