今更なんだけど、AVX命令

半年くらい前のニュースですが、Intelx86アーキテクチャの改善のために新命令フォーマットVEXと、VEXに基づくAVX命令群を追加するそうです。

もともと複雑だったx86命令セットアーキテクチャに、さらに増築を重ねた現在のx86命令は、複雑になりすぎており、命令プリデコード&デコードの負担は大きい。そして、Intelは、その部分の改良が、Nehalemの1対1電力効率の原則に合致しないことを明らかにした。つまり、x86命令の複雑性から来る問題は、改良しようとすると、トランジスタと電力を非常に食ってしまうので、電力効率の維持の観点から合理的ではないと判断された。

x86デコーダーが性能向上、というより熱効率向上の上で大きな足かせとなっていることは、何年も前から報じられていました。そこで命令フォーマットを変更してデコーダーを簡略化する方針のようです。が、ここで強調しておかないといけない点が二つ。

Intel後方互換性を持たない製品を出さない
かつてのIntel vs. Motorla戦争の時、Intelは常にOSレベルまでバイナリ互換を出し続けたのに、MotorolaはMC680x0シリーズで毎回OS部のアーキテクチャを変更したという経緯があります。これがあって、MC680x0を採用したメーカーは必ず新CPU対応が遅れ、しかも複数世代にまたがるOSの開発に足を取られることになりました。Motorolaは性能向上戦争でIntelに負けましたが、それ以前に鉄壁の守りと思われたワークステーション市場でRISCやi80368への顧客流出を止められなかった原因の一つが、OS互換性です。Intelはこれを知っていますから、今更互換性のない製品をメインストリームに出すなどあり得ません。
Intelは性能が落ちる製品を出さない
この点でIntelPentium ProとItaniumで痛い目にあっています。Pentium Proは16bit互換モードが下位機種のPentiumより遅く、ユーザーから総スカンを食らいました。また、ItaniumプロセッサもIA-32互換モードがあまりに遅いため、現行のインテルユーザーの取り込みに失敗しています。

Intelにとって現在のユーザーは宝であり、ないがしろにすれば次世代CPUはAMDの前にひれ伏さなければならなくなります。そんな選択肢があるはずはありません。ということは、AVX導入後もSSEは最低でも現在と同じ性能を持つはずです。なぜこんな回りくどいことを書くかというと、これを突き詰めると、AVXをSSEより引き立てるには、AVXを強化していくしかないという結論が必然的に導かれることを説明したかったからです。
で、AVXの強化ポイントですが、現在報じられているのは256bit並列演算の可能性です。しかし、私としてはレジスタの本数を増やす方に振れるんじゃないかと思います。何でかというと、現在の8本(64bitモードでは16本)というレジスタ数は、アルゴリズムに対する自由度が極端に小さいんです。少なくとも、一番内側のループの中で使うループ変数はレジスタにおくのが効率のよいコーディングです。しかし、8本という数はそれを許しません。仮に許してもそれは硬直した実装で、工夫を許しません。
長いパイプラインが作り出す、大レイテンシ・命令セットに対しては、ディレイ・スロットを頭に置いた最適化が必要になります。ディレイ・スロット対策に関しては、Intelはアウト・オブ・オーダー実行やハイパー・スレッディングを繰り出していますが、これで問題が解決するなら、だれもシングルスレッドの性能向上なんて言いやしません。解決しないんです。
方向としてベクトル演算能力の拡大を挙げるなら、XMMレジスタ数を最低32本、できれば64本程度まで拡張することは不可避に思えます。もちろん、そういった拡張は非常に危険です。論理レジスタ数を大幅に増やさないとOoO実行ができなくなりますし、なにより、レジスタ数の増大はレジスタ幅の拡大と違って実行周波数にストレートなダメージを与えかねません。そんなこんなで、Intelレジスタ数を増やすかどうかはわかりませんが、私は発熱をあまり増やさずに性能を挙げる方法としてはレジスタ長拡大よりレジスタ数拡大のほうが正しいと思いますね。
もうひとつの方向は、やはりSIMDと実際のアプリのギャップを埋める非整列アクセスとか非対称演算かなぁ。今朝の記事で

Gelsinger氏は次のように語る。
Larrabeeは『LNI』という新しい(IA-32アーキテクチャの)命令セット拡張だ、と言うこともできる。LNIは、汎用性がある完全な新命令セットだ。ベクタプロセッシングやスキャッタ/ギャザ、イレギュラデータ構造、といった全てを含む。非常に強力な命令セット拡張だ」

とあるから、その辺のギャップ埋めは鉄板かな。

/* -----codeの行番号----- */