パスワードを忘れた? アカウント作成
494096 journal

okuの日記: add が inc より速いという話 3

日記 by oku

デートスポットを探してネットをうろついていた筈が、何故か「関数型言語はC言語よりも高速」なる記事を探し当ててしまい、更にリンク先の IA-32 インテル(R) アーキテクチャー最適化 (PDF 注意) まで読んでしまうというヘタレな自分これあり。

いやまあですね、元記事のほうに書いてある、

まあ、そういう話。本来、関数型言語とか、そういう高級言語は、C言語よりも最適化できるはずなんだけど、まあ、なかなかそういうわけにはいかず、C/C++は人口が多いので、マンパワーで勝ってしまうというそういう話でした。

というのは先刻承知というか、C/C++ の場合 const ですら書き換えがないことの明示にはならないわけでして (mutable とか const_cast とかあるし以下略、っていうか Stroustrup 自身「const は最適化の役には立たない」って D&E か何かに書いていたはずだし)、更に言えば、分割してコンパイルした先のオブジェクトで何をやっていてどういう副作用があるかなんてコンパイラには知りようもないわけでして (確か Sun のコンパイラにはリンクフェーズで最適化する機能もあったと思いますが)、Cat 言語作者Language Purity and Dirty and Clean Functions で、副作用がないと明示することで最適化が簡単になると主張している所以もこの辺にあるわけです。

で、それよりびっくりしたのは、

君はinc命令がadd命令よりも遅い理由を知っているか!

という件です。 え~これってマジですか~ていうかそうすると今時のコンパイラって ++add にしたりするんですか、な、なんだって~というわけで「IA-32 インテル(R) アーキテクチャー最適化」を読んでいるという次第です。

追記:

「IA-32 インテル(R) アーキテクチャー最適化」の 2-59 に該当する記述がある模様です:

inc 命令と dec 命令は、フラグレジスター内の一部のビットだけを修正する。これによって、フラグレジスターのそれ以前の書き込みすべてに対する依存関係が発生する。特に、inc 命令と dec 命令がクリティカル・パス上にある場合は、これらの命令を使用して、他 の多くの命令が依存しているロード操作のアドレスが変更されるため、このことが大きな問題になる。

アセンブリ/ コンパイラー・コーディング規則42(影響 M、一般性 H)。inc 命令とdec 命令は、できるだけ add 命令と sub 命令で置き換える。add 命令と sub 命令はすべてのフラグを上書きするからである。inc 命令と dec 命令はすべてのフラグを上書きしないため、フラグをセットした前の命令に対して不正な依存関係が発生する。

要するに、inc はフラグの「一部分だけを書き換え」ないといけないので、以前のフラグレジスタを憶えておく必要があるのだけれど、add は「全部書き換え」だから、以前のフラグレジスタは捨ててもいい、と。 昔の 8086 や V30 みたく、incadd の実行サイクル数に違いがあった時代ならいざ知らず、今となっては inc を使ってもいいことないよ (オペランド分のメモリサイズの違いを気にしないのであれば)、ということのようです。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by tt (2867) on 2007年05月20日 21時19分 (#1160075) 日記
    定数掛け算をシフトと加減算に展開するのも遅くなることが多くなってきたようです。 いやまあ定数の値によって展開するかどうかを判断する必要があるのは昔から同じですが、どうも境界がどんどんと小さいほうになっているようで。複数のALUを占有したりデータ依存が発生する演算を行うより普通に掛け算しろってことらしいです。
    --
    -- Takehiro TOMINAGA // may the source be with you!
    • いっそ、μop (amd 用語だと rop だったか?) 直接書かせてくれよとかそういう感じのアレですね。 :-)

      最近の IA-64 のように x86 命令なぞソフトウェアでエミュレーションするのだ、というアイディアの方が今時はすっきりするような気がしてなりません。 まぁ、現実の市場では競合という存在がありますから、ソフトウェアエミュレーションで現行並みの性能が出せない限りは無理でしょうね...

      親コメント
      • 原理的には(RISC|IA-64|コードモーフィング|その他なんでも新しい設計のプロセッサ)のほうが速いはずなんだけど、マンパワーでIA-32が勝ってしまうという構図がC++ vs 関数型言語によく似てますね。
typodupeerror

開いた括弧は必ず閉じる -- あるプログラマー

読み込み中...