やまもと
数値計算ライブラリBLASに含まれる行列積ルーチンDGEMMを高速化していく手順を記した記事「行列積計算を高速化してみる」の章ごとに分割した記事をまとめたマガジンです。元の記事は20万文字以上になってしまったため、分割に踏み切りました。元記事が有料(560円)なので、分割した記事も一部有料(100円/記事)になっています。全記事を購入いただくと合計1000円になるため、元記事の方がお得になっています。
ハイパフォーマンスコンピューティング(HPC)で必要とされる高速なプログラムを書くための技術です。普通のプログラマーには、あまり必要ではありません。
研究部門に所属しているので、研究部門をマネジメントする方法を個人的に考えてみています。
現在、自己実現(self-actualiztion)という言葉は「目標を達成すること」という意味で用いられていることが多いように見えます。しかし、マズローの「人間性の心理学」の第4章を読んだ時は、自己実現は「自分がなるべくしてなった」という感じで、目標達成と印象が異なりました。 そこで、久しぶりに「人間性の心理学」を読んでみてたところ、第11章「自己実現的人間」の内容の詳細は一般に伝わっている内容とは異なる気がしました。 第11章では、サンプル数が少なく科学的とは言えない
前回、学生時代を振り返り、素粒子物理学で学習する必要のあった理論を図(下図)にしてみました。前回は量子力学あたりで力尽きたので、今回はその続きになります。 説明することが多すぎて、どうしても長くなってしまいますが、今回も詳細はWikipediaに任せます。もっと知りたい方は、ウェブ上にもたくさん情報があるので、この記事であげたキーワードで検索してみてください。 量子統計力学量子統計力学は、ミクロな粒子を「とびとびのエネルギー(エネルギー準位)」しかとり得ない量子として扱っ
前回の記事で、OpenBLASよりも7~8%性能が劣っていました。その後、いろいろ試していたのですが、2~4%ほど高速になったので、性能が向上したポイントを記録しておこうと思います。 ピーク性能比率でみると95~97%、FLOPS値でみるとおよそ45GFLOPSくらいなりました。それでも、OpenBLASよりも劣っているので、まだ工夫の余地はあるのでしょう・・・。 プリフェッチの見直しカーネル関数のプリフェッチに関しては第18回で書いていますが、第25回でカーネル関数を書
そこそこ高速な実装ができたので、他のBLASライブラリが持つDGEMMと性能比較を行ってみましょう。 比較を行うライブラリとしては、下記を使用しました。 1、BLAS(NetLibの参照実装) 2、ATLAS 3、OpenBLAS これらのライブラリについては、下記でも紹介しています。 GCCの準備評価環境として使用しているMacBookでは、OpenBLASはbrewでインストール可能でしたが、BLASとATLASは独自にコンパイルする必要がありました。 コンパイ
行列コピー関数は、行列積の計算量O(N^3)よりも計算コストが圧倒的に小さいことを利用して、以下の目的で導入しました。 (1)あらかじめ、行列データをキャッシュメモリに書き込んでおく (2)行列データを直列化し、行列積計算カーネルのキャッシュ利用効率を最大化 (3)DGEMMの転置オプションを行列コピー関数の差し替えで実現する これらに関しては、以下の記事をご参照ください。ただ、これらの記事は、実装や高速化にとって重要なポイントなので、有料記事にしています。 転置行列コ
当初の設計(下記の記事)では、I,J,Kループのキャッシュブロッキングサイズは、キャッシュメモリの容量に収まるように決めました。 しかし、L1キャッシュブロッキングの有無がカーネル関数の性能を左右していたため、性能実測しながらL1~L3のブロッキングサイズを変更することにしました。前回の記事のカーネル関数の性能は、ブロッキングサイズ改良後の測定値になります。 改良したブロッキングサイズ当初の設計では、キャッシュメモリのブロッキングサイズを下記のように設定していました。
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 以上で、行列積DGEMMの最適化手続きは全て完了しました。思ったよりも性能は出ませんでしたが、いったんこの記事は終了にします。 それでは、最終的にどの程度高速化できたのかを確認します。 計算速度の行列サイズに対する依存性を見るために、NxNの正方行列を対象として基本周波数の理論ピーク性能比を、N=16,32,...,2048で測定しました。
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 スケール関数の最適化も、コピー関数の最適化と同じの手続きを進めます。ただ、スケール関数はまだアンローリングを行っていないため、アンローリングから始めます。また、計算時間は非常に短いため、今回はアライメントの場合分けを見送ります。 最適化の手続き (1)アンローリング (2)ベクトライズ、アセンブラ化 (3)プリフェッチの挿入 (4)ループシフ
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 スケール関数は、下記の計算に使用します。 C = beta * C コピー関数と同様に、スケール関数も2つのテストプログラムを作成しておきます。 (1)処理結果確認プログラム・・・正解値と処理結果の比較 (2)処理速度測定プログラム・・・処理時間を測定 22-1. テスト用構造体行列積のテストプログラムと同様に、テストに必要な関数と引数
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 コピー関数の最適化の手続きは、行列積カーネルの手続きとほとんど同じです。唯一の違いは、コピー元である行列のアライメントが不明なため、アライメントが揃っている場合とそうでない場合で場合分けする点くらいです。 最適化の手続き (1)ベクトライズ、アセンブラ化 (2)プリフェッチの挿入 (3)ループシフト/命令順序の入れ換え (4)アライメントの場
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 行列積のテストプログラムは現在のものを使えば良いですが、行列A,Bのコピー関数は、行列積計算に比べ処理時間が短すぎて、現在のテストプログラムだと性能が向上したかどうかがほとんど分かりません。 そこで、コピー関数は独自にテストプログラムを用意することにします。行列積計算の場合と同様に、それぞれ下記の2つのプログラムを作成します。 (1)処理結
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 次に、各演算器の停止時間を最小化するために、5つの演算器を同時使用できる命令順序への変更を考えます。 今回のプログラムでは、FMA計算・ロード処理・詰め替え処理の3つを行っています。Skylake マイクロアーキテクチャでは、FMA計算は2つの演算器(port0, port1)、ロード処理も2つの演算器(port2, port3)、詰め替え処
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 次に、メインメモリからキャッシュメモリにデータを運んでおくために、プリフェッチを挿入します。プリフェッチには、ハードウェア・プリフェッチとソフトウェア・プリフェッチがあります。 ハードウェア・プリフェッチ = CPUが自動的に行うプリフェッチ ソフトウェア・プリフェッチ = プリフェッチ命令で行うプリフェッチ プリフェッチ命令は自由に挿入で
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 アセンブラ命令を選択したら、インラインアセンブラ機能を使ってプログラムを実装していきます。 前節では、MxNxKが4x4x8にアンロールされた場合だけを検討しましたが、実際には3×3×4=36通りの場合があります。 もっとも、K≧8, K&4, K&2, K&1のば場合の違いは、命令数が違うだけです。K≧8の場合さえ実装できてしまえば、K&
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 前述したように、コンパイラ最適化では効率的なベクトライズができないため、インラインアセンブラ機能でアセンブラ命令を直接使ってベクトライズを試みます。 そのためには、どの要素を同時に計算するかを設計しなければなりません。 設計のポイントは、処理全体の命令レイテンシーの合計値を可能な限り小さくすることです。なぜなら、総レイテンシー以上に速くする
この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 アセンブラ拡張命令セット(SSE2やAVX2など)では、メモリのアドレスがブロック境界にあるかどうか(アライメントされているか)で使用する命令が異なります。例えば、SSE2命令セットの場合、アライメントされていることが前提にあればMOVAPS命令が使用できますが、アライメントが不明の場合はMOVUPS命令を使用せざるを得ません。しかし、一般にM