マガジンのカバー画像

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

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

記事一覧

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

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

超高性能プログラミング技術のメモ(15)

実は、このメモは、行列-行列積計算C=ABを高速化するために必要な技術を記録してきました。今回は、いよいよその行列積計算の高速化に挑みたいと思います。

行列積DGEMMは、HPC業界ではTop500ランキングでもベンチマークプログラムとして使われていて、今でも世界最高速が競われています。近年は、ディープラーニングの畳み込み計算などにも利用されているよう

もっとみる
CPUIDでCPUスペックを確認する

CPUIDでCPUスペックを確認する

超高性能プログラミング技術のメモ(14)

2020/7/22 動作周波数追記。コア数を修正

ここまで書き残してきた超高性能プログラミングのメモは、アセンブラ命令を多用しているため、CPUのスペックに思いっきり依存しています。しかし、CPUは、パッケージやマイクロ・アーキテクチャによって、使用できる拡張命令セットや、キャッシュメモリのサイズなどが変わります。そのため、同じプログラムでも同じ性能は

もっとみる
【実装例】内積計算プログラムの高速化

【実装例】内積計算プログラムの高速化

超高性能プログラミング技術のメモ(13)
技術を忘れないように、書き残しています。

前回、内積計算を例に演算とメモリ転送のオーバーラップを説明しました。今回は、内積計算をちゃんと実装して、速度の比較をしてみました。

ベースコードの作成今回は、次のようなプログラムをチューニングしていくことにします。

double ddot(size_t n, const double* x, const do

もっとみる
演算とメモリ転送のオーバーラップ

演算とメモリ転送のオーバーラップ

超高性能プログラミング技術のメモ(12)
技術を忘れないようにメモしています。

今回から、浮動小数点演算の話に入りたいと思います。高性能化のポイントは、「レジスタスピルやパイプラインハザードを回避しながら、ロード命令のメモリ転送中に浮動小数点演算を同時実行させてしまうか」になります。

命令数のカウントここでは、複数のベクトルの内積を計算する擬似コードを考えてみましょう。

double* in

もっとみる
線形代数ライブラリ

線形代数ライブラリ

超高性能プログラミング技術のメモ(11)

数値計算を簡単に高速化できる線形代数ライブラリを紹介しておきます。

線形代数ライブラリとは?線形代数ライブラリとは、ベクトルと行列のかけ算や足し算を担うBLASと、連立線型方程式や固有値方程式、特異値分解の解法を担うLAPACKの2つをパッケージングしたライブラリです。昔は、これら以外にも多くのライブラリが存在しましたが、現在ではBLASとLAPACK

もっとみる
メモリアクセスパターン

メモリアクセスパターン

超高性能プログラミング技術のメモ(10)
技術を忘れないようにノートに書き残しています。

かなり時間が経ってしまいましたが、案外読まれているようなので、また少しずつ追加していこうと思います。プログラミング初心者向けではないので、読者はいないだろうと思っていました。

今回は、メモリアクセスパターンの違いによる性能の違いについて簡単に書きたいと思います。

メモリアクセス速度パソコンを使っていて処

もっとみる
キャッシュをコントロールする方法

キャッシュをコントロールする方法

超高性能プログラミング技術のメモ(9)
技術を忘れないようにノートに書き残しています。

今回は、キャッシュメモリにデータを乗せておく処理について書こうと思います。この処理は、行列積計算のようなアルゴリズムには必要になります。

メモリアクセス1回目を速くするブロッキングは、キャッシュに乗るサイズにデータ利用領域を制限する技術でした。この領域制限により、一度キャッシュにデータが格納されると、その後

もっとみる
キャッシュメモリを有効利用する方法

キャッシュメモリを有効利用する方法

超高性能プログラミング技術のメモ(8)
超高性能プログラミング技術を忘れないように記録しています。

今回は、汎用メモリ・キャッシュ・レジスタの記憶階層を有効活用するためのループブロッキング技術を記述していきます。

ここでは、多次元配列を対象とします。多次元配列の場合、メモリ上のデータの配置順序とアルゴリズム上のデータの使用順序が異なること多々あります。そうすると、ストライドアクセス(データを飛

もっとみる
ストリップマイニング

ストリップマイニング

超高性能プログラミング技術のメモ(7)
高性能プログラミングの技術を忘れないようにノートを書いています。今回は、ストリップマイニングについて書いておこうと思います。

ストリップマイニングストリップマイニングは、高性能プログラミングでよく用いられる改変方法です。ループを固定長の長さ毎に分けて実行するようにします。その方法は、ベクトル型コンピュータのベクトライザー(ベクトル化処理器)が行なっている改

もっとみる
高速memcpyの実装例

高速memcpyの実装例

超高性能プログラミング技術のメモ(6)
高性能プログラミングの技術を忘れないようにメモしています。今回は、memcpyを高性能化してみます。

仕様の確認C言語プログラマならほとんど知っていると思いますが、まずmemcpy関数のインターフェース仕様を確認します。ここでは、manコマンドで確認してみます。

$> man 3 memcpy

表示されたマニュアルから、SYNOPSISを見ると次のよう

もっとみる
経過時間の測定方法

経過時間の測定方法

超高性能プログラミング技術のメモ(5)
高性能プログラミングで必須の、経過時間測定の方法について書いておきます。

時間を測定する関数高性能プログラミングでは、処理が高速になっていくため、時間測定の解像度も高くないといけません。プログラミング言語に用意されているタイマー関数は解像度が低いため、システムコールを使う必要があります。近年のLinuxでは、下記のような関数を使うことができます。

ナノ秒

もっとみる
パイプラインハザードの防ぎ方

パイプラインハザードの防ぎ方

超高性能プログラミング技術のメモ(4)
自分の備忘録として、プログラミング技術のメモを書き残しています。
今回は、アセンブラならではのループの組み方について書いておきます。

ハザードが起こらないパターン前回書いたように、最小限の基本的な演算処理、ロード命令LD→演算命令OP→ストア命令STの順序では、必ずレジスタの使用順序がRAW(Read after Write)型になり、パイプラインハザード

もっとみる
レジスタスピルとパイプラインハザード

レジスタスピルとパイプラインハザード

超高性能プログラミング技術のメモ(3)
自分のための備忘録として、技術のメモを残しています。

第3回は、アセンブラ言語における主要なチューニングであるパイプラインハザードの回避とデータ転送の時間稼ぎについて書こうと思います。

レジスタスピル演算器が直接利用できるレジスタメモリ(以下、レジスタ)は、有限個しかありません。SIMD命令が使用できるXMM, YMM, ZMMレジスタは、x86アーキテ

もっとみる
キャッシュ構造とアラインメント

キャッシュ構造とアラインメント

超高性能プログラミング技術のメモ(2)
高性能プログラミングに必要なキャッシュメモリの基礎知識を記録しておきます。

なぜキャッシュメモリが必要なのか?CPUで実際に演算処理を行うと演算器は、CPU内部に実装されているレジスタ(メモリの1種)にあるデータしか使えません。そのため、アセンブラ言語レベルでは、ほとんどの演算処理は、次のようなステップを踏みます。

  1. 汎用メモリからレジスタにデー

もっとみる