call とか ret は無くてもなんとかなる
Linux Kernel の include/asm-i386/system.h の switch_to() マクロとかで使われていたりして,わりと有名なテクニックなのかもしれませんが,
とかは,機械的に
みたいに,スタックの頭に戻り番地をプッシュして,関数にジャンプする感じに書き換えられるのではないかと思いました.
ret もまぁ,
みたいに,適当に壊しても良いレジスタに戻り値を pop して間接ジャンプすれば大丈夫な気がします.
もちろん,本来一命令で済むものを,わざわざメモリ触った挙句命令数増やすのはバカバカしいので,実用性は無いわけですが.
アセンブラとか,x86 命令レベルのクロック数とか μOP (マイクロオペレーション) レベルの話とか全然わからない子なので,大きな勘違いをしている恐れがあります (ツッコミ期待)
最近の x86 は,インタフェースだけは x86 のままでも,中身は全然別物らしいです.一個の x86 的 CISC 命令が複数の μOP に分解されて実行されたり,逆に複数の命令が一個の μOP で実行できたり.
x86 レベルではレジスタは 8 つしかありませんが,たとえば Pentium 4 は,物理レジスタは 128 本あるそうです.なので μOP レベルでは,x86 命令からさらにレジスタ割付みたいなことが行われて,レジスタリネーミングとかいう最適化技術が使われていたりも.
アセンブリのレベルの見た目と,実際の速度が全然異なるようです.なので,よく 「高級言語なんて当てにするな,アセンブリリスト出して見ろ」 とか言う古いプログラマの人がいたりするようですが,最近の CPU はアセンブリ自体がある種の高級言語で,x86 命令が内部的には μOP に JIT されて,命令が分解されたりまとめられたり実行順序が勝手に変更されたり同時実行されたりレジスタリネーミングされてものすごいパイプライニングされたり,わけわからんことになってみたいなので,アセンブリ見ても本当に早いのかどうかはわからない気がします.
なんかとりとめなくなってしまいましたが,要するに niha さんとかが最近アセンブリプログラミングについて書いてるみたいなので,僕もなんとなく思いついたことを書いてみたくなっただけなのでした.
CPU って,ガチガチのハードウェアみたいに思われてますけど,現在の x86 CPU は,IA-32 っていう高級な CISC 命令セットを実行するための仮想機械 (VM) なんですよね.本当にガチのハードウェアは,μOP っていう,もっと細かいオペレーションを実行する,レジスタがいっぱいある RISC プロセッサです.そういう非常に複雑な二重構造になっているのに,あれだけの性能が出ているという奇跡.すごいなぁと思います.
# icc の最適化がすごくて,gcc とかは一生かなわないってのも,ある意味当たり前です.インテル社だけが,μOP の仕様や,それへの変換アルゴリズムなど,もろもろの内部の秘密テクノロジを知っているのですから,他のコンパイラベンダは,ベンチマークの結果から内部を推測して,最適化ルーチンを作るしかありません.そりゃ,一生追いつけませんよ
ということは,実は x86 命令セットに限らず,ppc とか sparc とか arm とか,他のプロセッサの命令セットもハードレベルで JIT して実行できるポテンシャルはあるのでは ? と.
インテルが μOP の仕様を公開してくれれば,それの上の LLVM みたいなフレームワークを被せて,ハードウェアとソフトウェアが協調して,高速に低レベル命令を実行する VM フレームワークみたいなのが作れて良いのになぁ,とか妄想したりも.
んでまぁ,ここまで巨大なブラックボックスの上で世界が動いているという現状を考えると,やっぱりフォーマルメソッドには一定の限界があるのかなぁ,とか思うわけです.
原理的には,全てをロジックで記述し尽くして,プロファイルとか泥臭いことしなくても,(実時間の許す範囲で) 可能な限りの最適化とか可能だと思うんですけど.企業が秘密を握っている限り,それは不可能.実験と計測の世界のままです.
やっぱり,プロセッサアーキテクチャもオープンになって欲しいというか,やはり究極的には,FPGA とかで,全て明確な世界に持ってくる必要があるのだと思います.アプリケーションの仕様に合わせて,逆算的に命令セットや,最適なハードウェアをロジカルに生成すると.まぁ,今のところは夢物語ですが.
あー,分岐予測か.確かに.call/ret の組が無いと,どこからどこまでが関数なのかわからないとか,そういう話なのかな ?
http://d.hatena.ne.jp/scinfaxi/20080711/1215724490
そういえば JVM とかも,手書きで作った変なパターンのバイトコードに対しては,あんまり JIT が効かないので,javac とかはむしろほとんど最適化しない,素直な構造のコードを吐くようになってるとかいう話があったような.つくづく x86 って,ハードウェアというよりは VM に近いよなぁ.
追記
敬愛している id:shinichiro_h さんと id:w_o さんに同時に dis られるという快挙を達成しましたので,大満足です!書いたかいがあるというもので,非常にうれしい.天にも昇る気分です (ドM)
http://d.hatena.ne.jp/shinichiro_h/20080711#1215786569
http://morihyphen.hp.infoseek.co.jp/log2/200807.html#07110
call foo
とかは,機械的に
pushl $1f
jmp foo
1:
みたいに,スタックの頭に戻り番地をプッシュして,関数にジャンプする感じに書き換えられるのではないかと思いました.
ret もまぁ,
pop %ecx
jmp *%ecx
みたいに,適当に壊しても良いレジスタに戻り値を pop して間接ジャンプすれば大丈夫な気がします.
もちろん,本来一命令で済むものを,わざわざメモリ触った挙句命令数増やすのはバカバカしいので,実用性は無いわけですが.
アセンブラとか,x86 命令レベルのクロック数とか μOP (マイクロオペレーション) レベルの話とか全然わからない子なので,大きな勘違いをしている恐れがあります (ツッコミ期待)
最近の x86 は,インタフェースだけは x86 のままでも,中身は全然別物らしいです.一個の x86 的 CISC 命令が複数の μOP に分解されて実行されたり,逆に複数の命令が一個の μOP で実行できたり.
x86 レベルではレジスタは 8 つしかありませんが,たとえば Pentium 4 は,物理レジスタは 128 本あるそうです.なので μOP レベルでは,x86 命令からさらにレジスタ割付みたいなことが行われて,レジスタリネーミングとかいう最適化技術が使われていたりも.
アセンブリのレベルの見た目と,実際の速度が全然異なるようです.なので,よく 「高級言語なんて当てにするな,アセンブリリスト出して見ろ」 とか言う古いプログラマの人がいたりするようですが,最近の CPU はアセンブリ自体がある種の高級言語で,x86 命令が内部的には μOP に JIT されて,命令が分解されたりまとめられたり実行順序が勝手に変更されたり同時実行されたりレジスタリネーミングされてものすごいパイプライニングされたり,わけわからんことになってみたいなので,アセンブリ見ても本当に早いのかどうかはわからない気がします.
なんかとりとめなくなってしまいましたが,要するに niha さんとかが最近アセンブリプログラミングについて書いてるみたいなので,僕もなんとなく思いついたことを書いてみたくなっただけなのでした.
CPU って,ガチガチのハードウェアみたいに思われてますけど,現在の x86 CPU は,IA-32 っていう高級な CISC 命令セットを実行するための仮想機械 (VM) なんですよね.本当にガチのハードウェアは,μOP っていう,もっと細かいオペレーションを実行する,レジスタがいっぱいある RISC プロセッサです.そういう非常に複雑な二重構造になっているのに,あれだけの性能が出ているという奇跡.すごいなぁと思います.
# icc の最適化がすごくて,gcc とかは一生かなわないってのも,ある意味当たり前です.インテル社だけが,μOP の仕様や,それへの変換アルゴリズムなど,もろもろの内部の秘密テクノロジを知っているのですから,他のコンパイラベンダは,ベンチマークの結果から内部を推測して,最適化ルーチンを作るしかありません.そりゃ,一生追いつけませんよ
ということは,実は x86 命令セットに限らず,ppc とか sparc とか arm とか,他のプロセッサの命令セットもハードレベルで JIT して実行できるポテンシャルはあるのでは ? と.
インテルが μOP の仕様を公開してくれれば,それの上の LLVM みたいなフレームワークを被せて,ハードウェアとソフトウェアが協調して,高速に低レベル命令を実行する VM フレームワークみたいなのが作れて良いのになぁ,とか妄想したりも.
んでまぁ,ここまで巨大なブラックボックスの上で世界が動いているという現状を考えると,やっぱりフォーマルメソッドには一定の限界があるのかなぁ,とか思うわけです.
原理的には,全てをロジックで記述し尽くして,プロファイルとか泥臭いことしなくても,(実時間の許す範囲で) 可能な限りの最適化とか可能だと思うんですけど.企業が秘密を握っている限り,それは不可能.実験と計測の世界のままです.
やっぱり,プロセッサアーキテクチャもオープンになって欲しいというか,やはり究極的には,FPGA とかで,全て明確な世界に持ってくる必要があるのだと思います.アプリケーションの仕様に合わせて,逆算的に命令セットや,最適なハードウェアをロジカルに生成すると.まぁ,今のところは夢物語ですが.
あー,分岐予測か.確かに.call/ret の組が無いと,どこからどこまでが関数なのかわからないとか,そういう話なのかな ?
http://d.hatena.ne.jp/scinfaxi/20080711/1215724490
そういえば JVM とかも,手書きで作った変なパターンのバイトコードに対しては,あんまり JIT が効かないので,javac とかはむしろほとんど最適化しない,素直な構造のコードを吐くようになってるとかいう話があったような.つくづく x86 って,ハードウェアというよりは VM に近いよなぁ.
追記
敬愛している id:shinichiro_h さんと id:w_o さんに同時に dis られるという快挙を達成しましたので,大満足です!書いたかいがあるというもので,非常にうれしい.天にも昇る気分です (ドM)
http://d.hatena.ne.jp/shinichiro_h/20080711#1215786569
http://morihyphen.hp.infoseek.co.jp/log2/200807.html#07110
