課題2: 逐次版LU分解プログラムの高速化

課題1 で完成させたプログラムの高速化を試みる。LU分解 を行うC言語の関数 に対して高速化を試みる。元の関数は消さずに残しておき、 速度比較ができるよう にする。速度比較は行列のサイズ n の変化に対し, LU分解に要する時間がどう変化するか調べること。

以下にはさまざまな高速化手法を示すが、 現在重要になっているのは キャッシュなどに関する局所性を高めることである。 TLBミス,キャッシュミスについて資料・説明 や学科の講義に基づきよく理解しておくことが望ましい。

すくなくともキャッシュミスを減らすような形で高速化を行うことを必須とするが、 すべての高速化手法を試す必要はない。 余力がある場合、他の実験履修者の速度を上回りたい場合などに参考にすること。

並列プログラムのサンプルの 最初の説明は高速化に関するものに なっているので参考に.

補足: ここの課題で行っているような密行列行列演算などの高速化は、 高速化自体が目的であれば「共通パターン」についてライブラリ化した BLAS ルーチン等を利用するのが現実的である。 しかし、本演習は各自、高速化を体験しようという趣旨なので、 BLASのような既存ライブラリを利用しないことになる。


浮動小数点演算

本演習・実験で用いる計算機システムでは,Intel 386 プロセッサ(と浮動小数点コプロセッサ387)の命令セットに基づくものになって いる。計算機室のプロセッサは何世代も後継の Intel Core 2 Duo で, Core2 に基づくものになっているが,命令セットは同じと考えてもよい。 浮動小数点演算はPentium 4 で追加されている SSE2, あるいは Prescott (Pentium 4 改良版)で追加されている SSE3 を用いたほうがよい可能性がある.SSE3を浮動小数点演算に用いるためには, gcc [その他のオプション] -msse3 -mfpmath=sse foo.c -o foo のようにする. 逆に、SSE2(SSE3)を用いない場合は 浮動小数点演算はレジスタスタックを用いているので、少し特別に考える 必要がある。

なお、計算機室の Intel Core 2 Duo は SSE4.1 もサポートしているので、 gcc [その他のオプション] -msse4.1 -mfpmath=sse foo.c -o foo とすることもできる。


Core 2 Duo 向けの最適化

ここ(外部リンク) の「 インテルR 64 アーキテクチャーおよび IA-32 アーキテクチャー最適化リファレンス・マニュアル [日本語: PDF 形式 8,974 KB]」が詳しい。 なお,計算機室の Linux端末は Hyperthreading には対応していない。

もちろん、gcc に Core 2 Duo向けの最適化を指示することも有効であろう。 計算機室のCore 2 Duo の場合は、 -mtune=core2 を指定する。 (なお、gcc バージョン3.4以降にのみ -mtune があり、 それ以前は -mcpu であった。また -march とすると指定したマシン(だけ)の 命令を生成する。)


より新しいコンパイラの利用

準備で述べたように, 計算機室の gcc にはバージョンが3つある(gcc, gcc34, gcc44)。 新しいものを使うことで性能が向上すると期待できる。


多重ループの入れ子の交換


一時変数の導入


強さの軽減


一時的な配列の導入


行列の転置


再帰的アルゴリズム


ブロック化(blocking)

LU分解に関するブロック化(blocking)を含めた詳細については、 こちらに示す。 なお、LU分解のブロック化などは検索でも見つかる。 しかし,検索でみつかるもののほとんどは, LU分解の分類で示した, Doolittle型(l_ii=1)について扱っている。 本演習では,クラウト(Crout)型(u_ii=1)について 扱っているので,注意すること。 (ヒント: 本演習では配列の添え字を除くと,CではなくFortran でのブロック化LU分解に近くなる)


ループ・アンローリング


プリフェッチ


ソフトウェア・パイプライニング


並列プログラミング, 先頭ページへ
Masahiro Yasugi