雑種路線でいこう

ぼちぼち再開しようか

機械語が分かると。。。

機械語を巡るid:shi3zさんの人気エントリから、id:hyoshiokさんがx86の高速化技術に話を振るとは思わなんだ。キャッシュコヒーレンシの話がプッツリ終わっているところとか微妙というか、なんとなく浮いている気もするが。まあ確かにSMPになるとパイプラインと違って最適化コンパイラ任せにできないし、プログラマが意識せねばならないことが増える。いまどきWindowsLinuxも、その辺をきっちり意識しているが、お陰で初学者には取っつきにくくなってしまった気もする。"Lions’ Commentary on UNIX (Ascii books)"とか読むと、大昔のUNIXってすげーシンプルだし。GOTO文とかも結構あって最初はギョッとしたけどね。
ところで命令をμOPSに落として云々という記事を初めて読んだのは10年くらい前に米BYTE誌のPentium Pro解説記事でだったか。まだ微妙にCISC/RISC論争が尾を引いていたり、NexgenがAMDに買収された頃の話である。Pentium Proは16bit命令の実行速度が遅く、サンクダウンするWindows 9xを動かすとPentiumよりも遅いこともあった。
確かx86命令をRISC命令セットに変換するというアイデアはNexgenが最初で、そのRISC86命令はAMDK6に引き継がれた。どっちにしてもスーパースカラやスーパーパイプライン、分岐予測、レジスタリネーミング等の手法がx86に持ち込まれた時点でCISC/RISC論争など無意味になったし、機械語機械語でなくなった訳だが。まあx86のように命令変換が行われていなかったとしても、RISCチップだって高速化のためにパイプラインとか分岐予測が出てきた時点で、機械語レベルの最適化を行うことは非常に難しくなった。MIPSの最適化コンパイラはCとアセンブラの間に、手動で最適化するための中間コードがあったっけ。
だから機械語を分かっても無意味ということではなくて、機械語まではどのx86でも共通なのだし、ごく一部を除くとOSもアプリケーションも大概は機械語までの抽象度で書かれていて、あなたが最適化コンパイラを書くとか、カーネルレベルでキャッシュメモリの利用をギリギリまで最適化しようとかでない限り、μOPSを意識する機会はないはずだ。だいたいMPUのステッピング毎に最適化されたコードを用意して元を取れる世界なんて、そうそうない。Pentium 4の時代はパイプラインが深かったので埋めるためには色々と考える必要があったり、HT対策でマルチスレッドの書き方を工夫する必要があったが、gccはその辺を考えてくれなくてAthlonと比べると性能が出なかったらしいが、最近はどうなんだろう。
吉岡さんの記事にはCore MAとかのMacro-OPs Fusionの話が含まれてないなと気づいて後藤さんの記事を読み返したのだが、この辺のマイクロアーキテクチャになると再びパイプラインが浅くなったので、μOPSまで意識しなくても性能が出るし、チューニングしても労多くして功少なしということか。まあ隠蔽しているのであれば、見えなくても支障がないようにしてくれることが技術的には正しい。そもそも後期Pentium 4のパイプラインが30段もあることがおかしいのである。マーケティングのためにギリギリまでクロックを上げて、あとは最適化コンパイラプログラマが頑張ればいいとでも考えたのだろう。
μOPSから先のことが見えないとか、何がどう並列実行されるか分からないことを隔靴掻痒というか、最適化が難しいよねと考える人は結構いるようで、ItaniumなんかはVLIWといって何と何を並列実行するかまでコンパイル時に決定する仕組みになっているので、本物の機械語でギリギリまで最適化できる。原理的には速くなりそうだしDBやERPでItaniumが採用された例はあるが、費用対効果の点では規模の経済が働かないこともあって難しいのだろうか。どうも最適化コンパイラ頼みは、急進的半導体屋の陥りがちな陥穽のようだ。
半導体は設計に時間がかかって柔軟性がないから、できるだけ面倒なことはソフトに寄せようというのは工学的に正しいアプローチである筈なのだが、Intelはi860、Itaniumと2回もこのアプローチで苦労している。あまり知られていないことだがNTカーネルはもともとi860を対象に移植性を持たせるカタチで開発され、それからx86に移植された。VLIWといえばTransmetaを忘れてはいけない。素晴らしい技術だったが、いつの間にリーク電流削減技術のライセンシング会社になってしまった。まぁVLIWに限らず、市場から去った斬新なアーキテクチャを追っかけるのは面白い。Intel iAPX432とか、Symbolicsとか、Thinking Machinesとか。生き残った技術だけをみても、時代の先を読むことは難しい。
ところでソフトウェアに負担のかかる急進的なアーキテクチャといえばメニーコアが目下のトレンドである。これもAzulがインドのソフトウェア技術者をレイオフしたり、両社は否定しているがSONYがCELLの生産ラインを東芝に売却すると報道されたり、前途多難のようだ。まぁSunのNiagaraは性能が出ているようだし、IntelLarrabeeとかも気になる。技術的には面白いのだが成功するかどうかは分からない。最適化の面倒な半導体は流行らないという法則に照らすと、なかなか前途多難である気もする。
とか何とかだらだら書いてきた訳だが、わたしは機械語が読めない。幼稚園の頃だか自宅にあったPC-6001用のHexダンプをみて、これは人間の読み書きする言語ではないと思った。打ち間違えても暴走するばかりでBASICと比べると不親切だしね。Z-80の裏レジが云々とか、NTVDMって仮想86モードに落ちるから云々とか、マイクロアーキ毎にパイプラインの構成とか違うからバイトコードを環境毎にJITコンパイルした方が最適化の余地が大きいかもねとか何となく分かったような口を利くが、正直いって機械語は読めない。
そういう言語が世の中にはあって、自分の書いたり使ったりしているプログラムが様々な経路を経て、そういう風に噛み砕かれていることは何となく知っているだけである。これまでの人生で機械語を知らなかったことで損したことはないが、それはきっと、ちゃんとプログラムを書いたことも数えるほどしかないからかも知れない。ということもあって機械語を操るひとは素直に尊敬する。世の中にはトグルスイッチから自分でつくったスパコンのOSを直接入力して一発で動かす変人天才とかもいて*1、そういうひとが大事にされる社会じゃないとね、とか、そういう人と張り合うのは止めておこう、とか思う訳だが。
そういう意味でid:shi3zid:hyoshiokのようなsuper hacker達と張り合うのは本意ではない。まぁ世のはてな村の住人の多くは僕と同じように、Linux kernelにあるhoge.Sとかを何度かlessとかで眺めて、はぁ、とか溜息をついて終わってるんじゃないかい。たぶんそれは普通のことだし、あまり心配しないでいい。ただ、そういう世界があって、あなたのパソコンのメモリにも、僕のパソコンのメモリにも、そういう機械語が詰まっていて、プログラムの性能上の問題を解く場合に、時折そういう層まで意識すると問題が解ける場合もあるくらいのことは、頭の片隅に置いておいて悪くない。
あなたの身の周りに機械語までブレークダウンして問題を把握できるプログラマがいるとしたら、それはきっとかなり幸せなことだ。ただ吉岡さんが書いているように、Z-80時代の実行モデルとモダンなMPUの実行モデルは大きく異なる。とはいえ世の中はもっと下らない問題に溢れていて、なかなかそういうディープなことでハマる機会は少ないのではないか。まぁ何というか、仕事にも友人にも恵まれたいものである。

実のところ機械語はマシンに対する高レベルな挙動を示す命令であって実行を厳密に写像したものではない。(何を言っているんだわたしは?)
マシン語ってどんな感じか知りたくなった方へ」という大人気のエントリと、ニコニコ動画を見て、昨今の最新マイクロプロセッサでは機械語がもはや機械の挙動と一対一に対応しなくなっちゃったのである、というツッコミをしたくなった。
(略)
シングルプロセッサでは、そーゆめんどうな事は、通常は観測できない。しかし、マルチコアになると、あるコアで書き込んだものを別のコアで利用するなんていうことが日常茶飯事で発生するのであるが、それについては別途なにがしかの方法が必要になってくるのである。

*1:スーパーコンピュータの Cray シリーズを設計したシーモア・クレイは、自ら設計したコンピュータに、自ら設計した OS を、丸ごとトグルスイッチで入力したと伝えられる。八進数で。寸分たりとも過たずに。そしてそれが動いた。なんと雄々しき超弩級「本物のプログラマ」であることよ。 出典:"A Brief History of Hackerdom"