アカウント名:
パスワード:
ここが意味不明ですね。
以前x86互換CPUを作っていた技術者から聞いた話ですが、IntelのCPUが命令キャッシュとデータキャッシュを独立して持つようになったときに、自己書き換え型のプログラムの実行も保証するように設計したらしいですね。
これは回路的にも動作的にも結構なオーバーヘッドになります。なぜなら、データキャッシュと命令キャッシュでコヒーレンシを保たないといけないからです。せっかく命令とデータに分かれているものをいちいち関連付けているわけですね。
コメント中の「スピード最優先」が何のスピードを指しているのかy読み取りずらいのですが、CPU開発スピード、もしくはCPU動作スピードをさしているとしたら、それは的外れなコメントです。
intelが優先したものは、CPU動作の互換性です。実装のきれいさとか、プログラミングのフィロソフィーは二の次だったのです。
やっぱわけわかんないですね。
自己書き換えプログラムが相当多いならば、ハードウェアで対処するというのは全体的な処理スピードを稼ぐことができます。ただし、CPUのクロック周波数を稼ぐことができないのは前に書いたとおりです。
しかし、自己書き換えはとイレギュラーなプログラミングです。意図的に書かないと作れないものです。これは自己書き換えプログラムが少数であることを示唆していると考えられます。
そうした場合、少数のプログラムでしかもイレギュラーなものの互換性を保つためにCPUのクロック
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲは一日にしてならず -- アレゲ研究家
ガード領域 (スコア:2, 参考になる)
小粋なことをしてなかったな~と改めて認識しますね。コード領域とデータ領域の
分離とかやった時代からだいぶ経つのに結局はスピード最優
Re:ガード領域 (スコア:1, 参考になる)
ここが意味不明ですね。
以前x86互換CPUを作っていた技術者から聞いた話ですが、IntelのCPUが命令キャッシュとデータキャッシュを独立して持つようになったときに、自己書き換え型のプログラムの実行も保証するように設計したらしいですね。
これは回路的にも動作的にも結構なオーバーヘッドになります。なぜなら、データキャッシュと命令キャッシュでコヒーレンシを保たないといけないからです。せっかく命令とデータに分かれているものをいちいち関連付けているわけですね。
コメント中の「スピード最優先」が何のスピードを指しているのかy読み取りずらいのですが、CPU開発スピード、もしくはCPU動作スピードをさしているとしたら、それは的外れなコメントです。
intelが優先したものは、CPU動作の互換性です。実装のきれいさとか、プログラミングのフィロソフィーは二の次だったのです。
Re:ガード領域 (スコア:1, 参考になる)
指したのはCPUの動作スピードです。なぜそれかというと、
> intelが優先したものは、CPU動作の互換性です。実装のきれいさとか、プログラミングのフィロソフィーは二の次だったのです。
互換CPU作っている以上、それはデフォルトですから議論以前の問題です。(互換性は有ってあたりまえ)
その互換を保った上で、如何に開発のスタンスをどちらの方向に持っていくかは
開発方針次第になります。もしくはWindowsの様に互換性を徐々に外していく方向性とか。
それはIntelの政治手腕も入ってくるので技術的な面だけ語っても意味は無いのですが、
互換性と一言で言っても、その上でできることは色々あります。
Re:ガード領域 (スコア:0)
やっぱわけわかんないですね。
自己書き換えプログラムが相当多いならば、ハードウェアで対処するというのは全体的な処理スピードを稼ぐことができます。ただし、CPUのクロック周波数を稼ぐことができないのは前に書いたとおりです。
しかし、自己書き換えはとイレギュラーなプログラミングです。意図的に書かないと作れないものです。これは自己書き換えプログラムが少数であることを示唆していると考えられます。
そうした場合、少数のプログラムでしかもイレギュラーなものの互換性を保つためにCPUのクロック
Re:ガード領域 (スコア:0)
そんな事ないんじゃないでしょうか。極端な事言えば
パフォーマンス>互換性…古くはi960、最近はIA-64
パフォーマンス<互換性…IA-32
互換性の重要性が認識される例 (スコア:0)
技術者2: そんなんたいしたことないじゃん。誰かが問題なし!といえばOKだよ。
…沈黙…
上司: じゃあ従来通り保証するということで。
Re:ガード領域 (スコア:0)
当時のプロテクトルーチンやブート時のROMから
RAMへ転送してから実行とか出来るようにするためでしょうか?
Re:ガード領域 (スコア:1, 参考になる)
WindowsのDOS窓でもいいけど、とにかく自己書き換えを
行うDOSアプリが残っていたということ。
# 現在でもまだ残っていると思う。
Re:ガード領域 (スコア:0)
Re:ガード領域 (スコア:0)
# スモールモデルでCS≠DS=SSだっけ?
# 当然、1セグメントは64KB
Re:ガード領域 (スコア:1)
自己書き換えってのが何処までを指すのかについては俺は疎いんですが、
気になるのが、わが愛しの(笑)Delphiは、
こんな風に「Object Instance」なるものを実行時に生成してる(ってことですよね?) [asahi-net.or.jp]って点です。
もしかして書き換えが禁止されたら、こういう高速化も駄目になるっすか?
それとも書き換えじゃなくて書き足しだと問題無いんでしょうか?
余談ですが、GUIライブラリを作るかたがたは、是非とも(?)、
他の言語やライブラリからバインドされる時のことを出来るだけ想定して、
言語側が任意(?)の「印」を個々のGUI部品に持たせられるようなデータ領域
(しかも高速にアクセス可能な)を用意しておいて頂けると、幸いです。
そうすりゃこんな難しい仕組み(実行時にコード生成なんて)は要らなくなるはず。
#…という意味(技術的に)だと理解しているんですが、間違いだったら突っ込んでください(^^;
GUI部品と言語のバインディング(に限らず、双方どちらもが主体者に成り得る状況)では、
双方が双方の「自分の相方」を低コストで区別できる仕組みがないと
辛そうですね。
平たい一例で言えば相互参照なポインタっていうか。
Re:ガード領域 (スコア:1)
実行時とはどこにも書かれてないようですが。
実行時に生成してるんじゃなくて、コンパイル時に処理してると思いますよ。
ウィンドウプロシージャの設定はコードの書きかえなどしなくても、実行時に普通にできますから問題ありません。
Re:ガード領域 (スコア:1)
あれ?そうですか?
「MakeObjectInstance にメソッドポインタを渡すと Object Instance を作成してくれます。
また FreeObjectInstance は Object Instance を削除してくれます。」
と書かれているのを、俺は「実行時にやるんだな」と解釈しました。
それにMakeだけならともかく
(実行時じゃなくコンパイル時に走らせるって手もあるかとも考えられそうなんで)、
Freeまで用意されてるってことは
(普通は「コードを」削除する必要なんて無いはずですよね。それもコンパイル時になんて。)、
これってやっぱり実行時なんじゃないでしょうか?
で、その生成/削除されるっていうObject Instanceなるものが何か?の説明のほうを見ると、
「Windows はメッセージ処理ハンドラが普通のプロシージャであると思っていますが、
我々(VCL)が欲しいのは、オブジェクトのメソッドの呼び出しです。
これを実現するには、いったんウィンドウからのメッセージを単純なプロシージャで受け、
そこからオブジェクトのメソッドを呼び出す仕掛けが必要です。
VCL では小さなコード片を使ってこれを実現しています。」
とのことです。
メソッドポインタ(Delphi用語に限らず一般論として)に必要なのは、
メソッドのコード自体へのポインタだけじゃなく、
selfつーかthisつまり対象オブジェクトへのポインタとか
(あるいはこの場合だとOS提供のWidgetのほうかな?どっちにせよ同じことですが)
のように、「実行時に」生成/削除されるモノへのポインタも含みます。
#Delphiも実行時のコードで自在にWidgetを生成/削除できます。当然ですが。
ってことは、ObjectInstanceは、
オブジェクトへのポインタを内在する「小さなコード片」でないとならない。
一言で言えば、Widget1つあたり、このコード片も1つづつ
存在してないとならない(そしてWidget消えたらコード片も捨てる)
っていう性質のもの、なのだと俺は理解しています。
で、そんなものは、実行時にでないと作れない、と。
間違ってるでしょうか?
----
ええと。他の環境で、Widgetの言語ラッパーを作ってみたときも、
この「相互」参照の問題に悩まされた記憶が少し有ります。
Widgetが「1つの」Cポインタを(プロシジャの関数ポインタのために)覚える余地は
用意してくれてるんですが、「2つ目の」Cポインタ(this)を覚えさせたくても
もう場所(構造体のメンバ変数だの、API関数の引数だの)に用意されてない、
ってなことがあったような。
#Winの場合は、あの頁によれば、用意はされてるものの遅い、ということのようですね。
#VBじゃ許せてもDelphiじゃ許せない、ってことでしょうか(^^;
で、仕方ないから、コールされる関数自体にthisを埋め込んじゃう、ということなのでしょうね。
C(Delphiも同じことです:てーかアセンブラつーかネイティブ)の「関数」のモデルだと
こういうクロージャみたいな情報(^^;を埋め込むには、結局泥臭いことをやらないとならんわけですよね。
それがObjectInstanceなるものなのだと理解しました。
----
>ウィンドウプロシージャの設定はコードの書きかえなどしなくても
あの文は、そういう問題ではない、という主旨なんだと理解しました。
その「設定」ってのは単に既に有るプロシジャのポインタを何処か(Widgetの中身)に代入する、
という意味だと思いますが、それだけだとWidgetがインスタンスを区別できないんで。
「区別」については、間接参照で間に合わす手は幾らでも有りますが、
たぶんそれらでは遅いってことなんでしょうね。
switch文みたいなものも要らない(前述のようにWidgetとラッパObjectの数自体が
実行するまで予測不能なので、switch的なことをしようとすれば結局
Hashtableみたいなもので動的にやる羽目になります。そりゃ遅いでしょうね。
GUIイベントが来るたびにそれをやっていたのでは、ちょっとねえ…)
ようにするには、Widget自体がthisを知っているか、それが駄目なら或いは
Widgetから直接呼ばれるコード「が」直接thisを知っているか、ってことなんでしょうね。
普通ならコードに引数を渡せば済むんですが、それを(素早く)渡す事が出来るモノが存在しないそうなので、
泥臭く埋め込まざるを得ない、と。
Delphiは実に欲張りです。
動的言語みたいなこともしたいくせに、
コンパイル静的言語のメリットも出来るだけ残したがってる。
そういう節が端々に感じられます。興味深い。
Re:ガード領域 (スコア:1)
Windowのプロパティを使うと遅いっていうのは、Windows3.1時代の名残りでなく今でも重要なんでしょうか。
まあBorlandはライブラリの実行速度に気をつかっているようですから、今から実装し直しても同じようなことになりそうですけどね。
#VCLのソースを読んで結構ショックを受けたり。
Re:ガード領域 (スコア:1)
生成したコードをファイルに吐き出してダイナミックリンクすればOKです。:-)
なんていう冗談はさておき、安全のためにはコード領域(とその中のコード)の
生成を全てOSに任せるべきなんでしょうね。
そうした場合、オンメモリでのコード生成を許可するべきかどうかは
微妙なところだと思います。
(出来なきゃ不便、出来ると危険)
Re:ガード領域 (スコア:1)
Widgetを動的に生成するたびにDLLも1つづつ動的に生成しろ、と?(^^;;;
(上に書いた俺理解が間違ってなければの話ですが)
>生成を全てOSに任せるべきなんでしょうね
まあ、「関数」と「コード領域」がイコールな言語を前提としてるってのが
そもそもの痛さの始まりなんですけどね。
これがLispみたいに状態(クロージャ?)をも関数が持てて
関数の複製(や、そのついでに状態を付加する)が出来るっていうなら
悩みは無かったのですが。
Widgetとかは、C言語の意味での関数のポインタが渡されることしか
想定していない(つまり「直接」Callされる)ので、
勝手にLisp風関数のポインタを渡すわけにもいかず。
Widgetについてはですが(どれだけ一般化できる話なのかは俺には判りませんが)、
「人を呪わば穴二つ」と思っています。つまり、
(C的な)関数と、データと、の2つのポインタが、結局最低限必要なんですよね。
言語側が用意してる任意のデータ構造(Objectとか)を解釈するためには、
それを解釈できる(最低でもCの)関数も与える必要があるわけで。
-----
CodeのVerifierが作れるならばイイんですけどね。
つまり、生成(やロード)したコードをVerifyする義務が有れば
動的生成だからってビビる必要が無くなるはずで。
#ん。これってJavaか?
Re:ガード領域 (スコア:0)
MakeObjectInstance 関数は Win32 API の VirtualAlloc 関数で
実行可能属性付きのメモリ領域を確保してそこにx86コードを生成しています。
このプロテクトでも、実行可能属性付きとして確保されたメモリ領域の
実行はいくらなんでも許してくれるんじゃないかな。