ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

Cプログラム高速化研究班

Cプログラム高速化研究班 コードを高速化する20の実験と達人の技 読みました。
Cの最適化について実体験を元に、プロファイルの結果等を交えながら、いろんな角度からの最適化について書かれた本です。実践的か、と言われるとすぐに実践に役に立ちそうな話は無いのですが、知っていて損は無いテクニックが紹介されています。

対象読者

ある程度Cでプログラムを書いたことがあって、デバッガを使ったデバッグ経験は必須です。というのも、いろんな最適化の話がでてきますが、Cの規格上の話なのか、gccの話なのか、x86アーキテクチャの話なのか、いろいろごっちゃになって出てきます。そこの所を自分で調べられないと、逆に間違った知識を持ってしまう危険があります。というのも、この手の本には必須だと思われる正確な一次情報へのポインタが全くありません。例えば、Xeonを例にとってキャッシュサイズとアクセス速度の考察をしていますが、キャッシュサイズの根拠となるIntelの資料へのポインタはありません。ほかにも「Cの変数は、register宣言でどのレジスタに割り当てるかを指定できるようになっていますよね(p73)」のように、特定のコンパイラの話をCの規格で保証されているかのような表現が使われています。読んでいて気になるところは自分で一次資料を探して調べないといけません。多分、そういう裏を取っていくと、この値段では収まらないんでしょうね。ある程度、読み物と割り切って読んだ方が良いです。

コンパイラの最適化を防ぐ例

この本で紹介されているテクニックを一つ紹介します。この本は最適化の話もあるのですが、正確にプロファイルする為に最適化を抑止する話も出てきます。
例えば、加算の最適化を防ぐ例です。

switch (argc > 4 ? atoi(argv[4]) : 0 {
    case 0: goto L0; case 1: goto L1; case 2: goto L2;
    case 3: goto L3; case 4: goto L4; case 5: goto L5;
    case 6: goto L6; case 7: goto L7; case 8: goto L8;
    case 9: goto L9;
}
do { 
   L0: a += b;
   L1: a += b;
   L2: a += b;
   L3: a += b;
   L4: a += b;
   L5: a += b;
   L6: a += b;
   L7: a += b;
   L8: a += b;
   L9: a += b;
} while(--n > 0);

実行したい行にgotoで飛び込むラベルをつけることで命令がまとめられてしまうのを防ぎ、コンパイル時に決まらない情報を使うことでラベル自体が削除されないようにしています。コンパイラに間違いが無いように指示を与えている様子は、見ているだけで面白いですね。この手の話が好きな人は、買って損は無いです。

業務システム向けのチューニング

この本の最後に、実際に開発で使われた大規模なデータに対する処理のチューニングが書いてあります。これ自体とても面白いのですが、ほとんどがデータを静的に解析してチューニングしています。今時の若いエンジニアだったら、C以外のリッチな言語の機能とライブラリを使って、この大規模データをどのように処理するのかは聞いてみたいなと思います。

最後に

クラウドだのビッグデータだの言われる2012年にもなって、この手の本が日本語で読めるのはとても幸せなことです。リッチな言語を使っていると気がつかずに通り過ぎてしまいそうですが、プログラミングとはそもそもCPUやデータとの対話な訳で、原点に目を向ける意味でも良い本だと思います。