やまもと

物理学博士/MBA。大手IT企業勤務する研究者です。最近は経営学や組織心理学の周辺を研…

やまもと

物理学博士/MBA。大手IT企業勤務する研究者です。最近は経営学や組織心理学の周辺を研究しています。 以前は、量子化学シミュレーション開発/HPCエンジニアをしていたので、その時に学習した技術を中心に書くつもりです。[FB] https://bit.ly/35ygatu

マガジン

  • 行列積計算を高速化してみた

    数値計算ライブラリBLASに含まれる行列積ルーチンDGEMMを高速化していく手順を記した記事「行列積計算を高速化してみる」の章ごとに分割した記事をまとめたマガジンです。元の記事は20万文字以上になってしまったため、分割に踏み切りました。元記事が有料(560円)なので、分割した記事も一部有料(100円/記事)になっています。全記事を購入いただくと合計1000円になるため、元記事の方がお得になっています。

  • 超高性能プログラミング技術のメモ

    ハイパフォーマンスコンピューティング(HPC)で必要とされる高速なプログラムを書くための技術です。普通のプログラマーには、あまり必要ではありません。

  • 企業における研究マネジメントの考察

    研究部門に所属しているので、研究部門をマネジメントする方法を個人的に考えてみています。

最近の記事

物理学の地図#2

前回、学生時代を振り返り、素粒子物理学で学習する必要のあった理論を図(下図)にしてみました。前回は量子力学あたりで力尽きたので、今回はその続きになります。 説明することが多すぎて、どうしても長くなってしまいますが、今回も詳細はWikipediaに任せます。もっと知りたい方は、ウェブ上にもたくさん情報があるので、この記事であげたキーワードで検索してみてください。 量子統計力学量子統計力学は、ミクロな粒子を「とびとびのエネルギー(エネルギー準位)」しかとり得ない量子として扱っ

    • もう少し高速になりました。|行列積高速化#29

      前回の記事で、OpenBLASよりも7~8%性能が劣っていました。その後、いろいろ試していたのですが、2~4%ほど高速になったので、性能が向上したポイントを記録しておこうと思います。 ピーク性能比率でみると95~97%、FLOPS値でみるとおよそ45GFLOPSくらいなりました。それでも、OpenBLASよりも劣っているので、まだ工夫の余地はあるのでしょう・・・。 プリフェッチの見直しカーネル関数のプリフェッチに関しては第18回で書いていますが、第25回でカーネル関数を書

      • OpenBLAS, ATLAS, BLASとの性能比較|行列積高速化#28

        そこそこ高速な実装ができたので、他のBLASライブラリが持つDGEMMと性能比較を行ってみましょう。 比較を行うライブラリとしては、下記を使用しました。 1、BLAS(NetLibの参照実装) 2、ATLAS 3、OpenBLAS これらのライブラリについては、下記でも紹介しています。 GCCの準備評価環境として使用しているMacBookでは、OpenBLASはbrewでインストール可能でしたが、BLASとATLASは独自にコンパイルする必要がありました。 コンパイ

        • 転置行列コピー関数の改良|行列積高速化#27

          行列コピー関数は、行列積の計算量O(N^3)よりも計算コストが圧倒的に小さいことを利用して、以下の目的で導入しました。 (1)あらかじめ、行列データをキャッシュメモリに書き込んでおく (2)行列データを直列化し、行列積計算カーネルのキャッシュ利用効率を最大化 (3)DGEMMの転置オプションを行列コピー関数の差し替えで実現する これらに関しては、以下の記事をご参照ください。ただ、これらの記事は、実装や高速化にとって重要なポイントなので、有料記事にしています。 転置行列コ

        物理学の地図#2

        マガジン

        • 行列積計算を高速化してみた
          30本
        • 企業における研究マネジメントの考察
          13本
        • 超高性能プログラミング技術のメモ
          15本

        記事

          ブロッキングサイズの改良|行列積高速化#26

          当初の設計(下記の記事)では、I,J,Kループのキャッシュブロッキングサイズは、キャッシュメモリの容量に収まるように決めました。 しかし、L1キャッシュブロッキングの有無がカーネル関数の性能を左右していたため、性能実測しながらL1~L3のブロッキングサイズを変更することにしました。前回の記事のカーネル関数の性能は、ブロッキングサイズ改良後の測定値になります。 改良したブロッキングサイズ当初の設計では、キャッシュメモリのブロッキングサイズを下記のように設定していました。

          ブロッキングサイズの改良|行列積高速化#26

          行列積の性能測定|行列積高速化#24

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 以上で、行列積DGEMMの最適化手続きは全て完了しました。思ったよりも性能は出ませんでしたが、いったんこの記事は終了にします。 それでは、最終的にどの程度高速化できたのかを確認します。 計算速度の行列サイズに対する依存性を見るために、NxNの正方行列を対象として基本周波数の理論ピーク性能比を、N=16,32,...,2048で測定しました。

          行列積の性能測定|行列積高速化#24

          行列スケール関数の最適化|行列積高速化#23

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 スケール関数の最適化も、コピー関数の最適化と同じの手続きを進めます。ただ、スケール関数はまだアンローリングを行っていないため、アンローリングから始めます。また、計算時間は非常に短いため、今回はアライメントの場合分けを見送ります。 最適化の手続き (1)アンローリング (2)ベクトライズ、アセンブラ化 (3)プリフェッチの挿入 (4)ループシフ

          有料
          100

          行列スケール関数の最適化|行列積高速化#23

          行列スケール関数のテストプログラム作成|行列積高速化#22

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 スケール関数は、下記の計算に使用します。 C = beta * C コピー関数と同様に、スケール関数も2つのテストプログラムを作成しておきます。 (1)処理結果確認プログラム・・・正解値と処理結果の比較 (2)処理速度測定プログラム・・・処理時間を測定 22-1. テスト用構造体行列積のテストプログラムと同様に、テストに必要な関数と引数

          行列スケール関数のテストプログラム作成|行列積高速化#22

          行列コピー関数の最適化|行列積高速化#21

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 コピー関数の最適化の手続きは、行列積カーネルの手続きとほとんど同じです。唯一の違いは、コピー元である行列のアライメントが不明なため、アライメントが揃っている場合とそうでない場合で場合分けする点くらいです。 最適化の手続き (1)ベクトライズ、アセンブラ化 (2)プリフェッチの挿入 (3)ループシフト/命令順序の入れ換え (4)アライメントの場

          有料
          100

          行列コピー関数の最適化|行列積高速化#21

          行列コピー関数のテストプログラム作成|行列積高速化#20

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 行列積のテストプログラムは現在のものを使えば良いですが、行列A,Bのコピー関数は、行列積計算に比べ処理時間が短すぎて、現在のテストプログラムだと性能が向上したかどうかがほとんど分かりません。 そこで、コピー関数は独自にテストプログラムを用意することにします。行列積計算の場合と同様に、それぞれ下記の2つのプログラムを作成します。 (1)処理結

          行列コピー関数のテストプログラム作成|行列積高速化#20

          アセンブラ命令順序の最適化|行列積高速化#19

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 次に、各演算器の停止時間を最小化するために、5つの演算器を同時使用できる命令順序への変更を考えます。 今回のプログラムでは、FMA計算・ロード処理・詰め替え処理の3つを行っています。Skylake マイクロアーキテクチャでは、FMA計算は2つの演算器(port0, port1)、ロード処理も2つの演算器(port2, port3)、詰め替え処

          有料
          100

          アセンブラ命令順序の最適化|行列積高速化#19

          プリフェッチの挿入|行列積高速化#18

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 次に、メインメモリからキャッシュメモリにデータを運んでおくために、プリフェッチを挿入します。プリフェッチには、ハードウェア・プリフェッチとソフトウェア・プリフェッチがあります。 ハードウェア・プリフェッチ = CPUが自動的に行うプリフェッチ ソフトウェア・プリフェッチ = プリフェッチ命令で行うプリフェッチ プリフェッチ命令は自由に挿入で

          プリフェッチの挿入|行列積高速化#18

          アセンブラによるベクトル化|行列積高速化#17

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 アセンブラ命令を選択したら、インラインアセンブラ機能を使ってプログラムを実装していきます。 前節では、MxNxKが4x4x8にアンロールされた場合だけを検討しましたが、実際には3×3×4=36通りの場合があります。 もっとも、K≧8, K&4, K&2, K&1のば場合の違いは、命令数が違うだけです。K≧8の場合さえ実装できてしまえば、K&

          有料
          100

          アセンブラによるベクトル化|行列積高速化#17

          ベクトル化の設計|行列積高速化#16

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 前述したように、コンパイラ最適化では効率的なベクトライズができないため、インラインアセンブラ機能でアセンブラ命令を直接使ってベクトライズを試みます。 そのためには、どの要素を同時に計算するかを設計しなければなりません。 設計のポイントは、処理全体の命令レイテンシーの合計値を可能な限り小さくすることです。なぜなら、総レイテンシー以上に速くする

          ベクトル化の設計|行列積高速化#16

          アライメントを揃える方法|行列積高速化#15

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 アセンブラ拡張命令セット(SSE2やAVX2など)では、メモリのアドレスがブロック境界にあるかどうか(アライメントされているか)で使用する命令が異なります。例えば、SSE2命令セットの場合、アライメントされていることが前提にあればMOVAPS命令が使用できますが、アライメントが不明の場合はMOVUPS命令を使用せざるを得ません。しかし、一般にM

          アライメントを揃える方法|行列積高速化#15

          インラインアセンブラの書き方|行列積高速化#14

          この記事は、以下の記事を分割したものです。 [元の記事]行列積計算を高速化してみる 一括で読みたい場合は、元の記事をご覧ください。 アンローリングの次は、ベクトライズ(SIMD化)に取り組みます。現在のプログラムでもコンパイラがSIMD命令に置き換えてくれますが、残念ながら効率的ではありません。そこで、直接アセンブラ命令を指定し、強制的に効率的なベクトライズを行います。 しかし、全てをアセンブラ言語で記述するとなると、厄介な点があります。例えば、関数の引数はOS(Wind

          インラインアセンブラの書き方|行列積高速化#14