Closed17

CSAPP 第5章 プログラム性能の最適化

bayamasabayamasa

メモリエイリアシング

あるポインタの中身が他のポインタを指していること

int a = 2;
int *b;

b = &a;
bayamasabayamasa

インライン展開(インラインてんかい、英: inline expansion または 英: inlining)とは、コンパイラによる最適化手法の1つで、関数を呼び出す側に呼び出される関数のコードを展開し、関数への制御転送をしないようにする手法。これにより関数呼び出しに伴うオーバーヘッドを削減する。

bayamasabayamasa

最適化プログラミングその1
コード移動

void lower1(char *s)
{
  long i;
  for( i = 0; i <strlen(s); i++)
}
void lower2(char *s)
{
  long i;
  long len = strlen(s);
  for( i = 0; i < len; i++)
}

lower1→lower2にすることで、for の繰り返し回数 × strlen の処理を短縮できる

bayamasabayamasa

最適化プログラミングその2
不要なメモリ参照の削除

void combine3(data_t *data, data_t *dest)
{
 long length = strlen(data)
 for (i = 0; i < length; i++)
 {
  *dest = *dest * data[i];
 }
}

void combine4(data_t *data, data_t *dest)
{
 long length = strlen(data)
 data_t acc = *data
 for (i = 0; i < length; i++)
 {
  acc = acc * data[i];
 }
  *dest = acc;
}

計算をする際に毎回関節参照をすることで、mov命令などのメモリ参照系の命令が余計にかかる。
accumulateするための一時変数に結果を格納して、計算することにより速度が向上する

bayamasabayamasa

アウトオブオーダーユニット
アウトオブオーダー(Out-of-Order)は、プログラムに記述された命令の順番に関係なく、処理に必要なデータが揃った命令から実行する仕組みです。

インオーダーの場合は、命令順序に従って実行を行うが、アウトオブオーダーはメモリアクセスの時間などを短縮するために、アクセスなどが不要な命令から先に実行する。
そのときにメモリアクセスが必要な命令は並行でフェッチしておく。

https://www.fujitsu.com/jp/products/computing/servers/unix/term/outoforder/#:~:text=アウトオブオーダー(Out-of,することができます。

bayamasabayamasa

分岐の場合においても、分岐命令がどちらかわかる前に実行をおこなう

bayamasabayamasa

レイテンシ限界
スループット限界

ハードウェアとしての限界。
スループット限界は並列処理によって改善することが可能

bayamasabayamasa

再結合変換
変数accに対して計算順序を変更することにより、メモリへのアクセスの依存性をなくし、並列処理を実現することができる

acc = (acc * 100) * data[i]

acc = acc * (100 * data[i])
bayamasabayamasa

レジスタスピル
ループアンローリングによって並列化を確保することによりスループット高速化を実現するが、
並列処理がレジスタの最大数を超えてしまうと、レジスタはその並列処理した結果をスタック領域に格納するようになる。

これによりスタック領域から値を取り出す作業が必要となり、並列数が少ない処理の方が返って処理速度が高いという現象が起きてしまう。
これをレジスタ spill (もれ)という。
https://note.com/ymzo76/n/nf50707ca707a

bayamasabayamasa

メモリ読み出しによるレイテンシ低下はアドレスを読み込んだ際に判断できるので、コンパイラ側がそれを認識することができない。

よって最適化などはできず、クリティカルパスになりやすい。

このスクラップは2021/09/18にクローズされました