問題タブ [opcode]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
php - PHP オペコード キャッシング/Zend アクセラレーションと include_once と require_once の比較
私たちの PHP ベースのアプリケーションのために、オペコード キャッシング/Zend アクセラレーション (これらは同じものだといつも思っていました) を調べている同僚がいます。彼のベンチマークは、require_once を使用して (大規模な) クラス ライブラリを含めてもパフォーマンスが向上しないことを示しているようですが、include_once を使用するとパフォーマンスが向上します。
これは私たち二人にとって生臭いにおいがしますが、ベンチマークの方法論を自分でチェックする時間はありません。私の同僚は私よりも魚のにおいに対して寛容です. :)
誰もこのようなことに遭遇したことがありますか? そうでない場合、include_once から require_once に切り替えることでパフォーマンスが向上したように見える原因となっている可能性のある他のことについて何か考えはありますか?
c++ - ヒープに格納されたコードを vc++ から呼び出す
私がこのようなことをしていると想像してください:
関数であるかのように p を呼び出す関数ポインタを定義するにはどうすればよいですか? (私は VC++ 2008 Express を使用しています)。
ありがとう
assembly - 誰かがこの直接組み立てられたx86JMPオペコードを説明できますか?
学校では、ブートストラッププログラムを使用して、オペレーティングシステムなしでスタンドアロンプログラムを実行しています。私はこのプログラムを研究してきましたが、プロテクトモードを有効にすると、プログラム内でオペコードとオペランドをデータとして直接アセンブルすることで、はるかに大きなジャンプが実行されます。これはGNUアセンブラ用でした:
まず第一に、なぜ(命令ニーモニックの代わりに)これを実行したいのでしょうか?
私はIntelのマニュアルを見てきましたが、それでもコードに少し混乱しています。具体的には、ボリューム2A、3-549ページに、オペコードの表があります。関連するエントリ:
実際のオペコードは明らかですが、最初のバイトである0x66は私を混乱させます。Intelマニュアルの表を参照すると、cpは明らかに6バイトのオペランドが続くことを意味します。そして明らかに次の2行に6バイトが続きます。0x66は、「オペランドサイズのオーバーライドプレフィックス」をエンコードします。これはテーブルのcpと何の関係がありますか?cpには16進値があると思っていましたが、代わりにこのオーバーライドプレフィックスがあります。誰かが私のためにこれを片付けてくれませんか?
これがodからのダンプです:
TARGET_ADDRESSは0x00010000として定義されました。
また、最後の2バイトの重要性にも少し混乱しています。しかし、それはまったく別の質問のようです。かなり遅くなっていて、コードとIntelのマニュアルを何時間も見つめているので、自分の主張が理解できたと思います。
見てくれてありがとう!
opcode - 未処理の矮星式
次のセグメンテーション違反が正確に何を意味するのか誰か教えてもらえますか?
そのsolaris 10 i386上。
アドバイスをいただければ幸いです。
c# - C# を使用して PHP スクリプトを OpCode に変換する最も簡単な方法は?
C#を使用してPHPスクリプト(.php)をOpCode/Bytecode(オペレーションコード)に変換する最も簡単な方法は何ですか? 必要に応じて DLL を使用できます。
PHPコードを簡単に分析するために、私が取り組んでいるプロジェクトでこれを行う必要があります。
どんな考えやアイデアでも大歓迎です。
ruby - RubyVM の putspecialobject オペコードはどのように機能しますか?
私はRubyVMの実装に取り組んでおり、オペコードに関するいくつかのドキュメントを探しましたが、役に立ちませんでした。
オペコードがどのように機能するかを具体的に知っている人putspecialobject
、または完全なドキュメントへのリンクを知っている人がいれば、とても感謝しています!
performance - VM 設計: オペコードを増やすか、オペコードを減らすか? 何が良いですか?
ショックを受けないでください。これは多くのテキストですが、詳細な情報を提供しないと、これが何であるかを実際に示すことはできません (そして、私の質問に実際には対応していない多くの回答が得られる可能性があります)。そして、これは間違いなく割り当てではありません(誰かが彼のコメントでばかげて主張したように)。
前提条件
この質問は、少なくともいくつかの前提条件が設定されていない限り、おそらくまったく答えられないため、前提条件は次のとおりです。
- 仮想マシン コードは解釈されます。JIT コンパイラーが存在することは禁止されていませんが、設計はインタープリターをターゲットにする必要があります。
- VM は、スタック ベースではなく、レジスタ ベースである必要があります。
- 答えは、レジスタの固定セットがあることも、それらの数に制限がないことも想定していない可能性があります。
さらに、「より良い」のより良い定義が必要です。考慮しなければならないプロパティがいくつかあります。
- ディスク上の VM コードのストレージ領域。もちろん、ここですべての最適化を破棄してコードを圧縮することもできますが、これは (2) に悪影響を及ぼします。
- デコード速度。コードを直接実行できるものに変換するのに時間がかかりすぎる場合、コードを保存する最善の方法は役に立ちません。
- メモリ内のストレージ スペース。このコードは、さらにデコードするかどうかに関係なく、直接実行できる必要がありますが、さらにデコードが必要な場合、このエンコードは実行中および命令が実行されるたびに行われます (コードのロード時に 1 回だけ行われるデコードは項目 2 にカウントされます)。
- コードの実行速度 (一般的なインタープリター手法を考慮)。
- VM の複雑さと、そのためのインタープリターを作成するのがいかに難しいか。
- VM 自体が必要とするリソースの量。(VM が実行するコードのサイズが 2 KB で、瞬きするよりも速く実行される場合、それは適切な設計ではありませんが、これを行うには 150 MB が必要であり、その起動時間はコードの実行時間よりもはるかに長くなります。実行されます)
ここで、多かれ少なかれオペコードが実際に意味することの例を示します。操作ごとに 1 つのオペコードが必要なため、オペコードの数が実際に設定されているように見える場合があります。ただし、それほど簡単ではありません。
同じ操作に対する複数のオペコード
のような操作ができます。
R1 と R2 の値を加算し、結果を R3 に書き込みます。ここで、次の特殊なケースを検討してください。
これらは、多くのアプリケーションで見られる一般的な操作です。既存のオペコードでそれらを表現できます (最後のオペコードがレジスタではなく int 値を持っているために別のオペコードが必要な場合を除く)。ただし、これらに対して特別なオペコードを作成することもできます。
前と同じ。メリットはどこ?ADD2 は 3 つではなく 2 つの引数のみを必要とし、INC は 1 つしか必要としません。したがって、これはディスク上および/またはメモリ内でよりコンパクトにエンコードできます。いずれかの形式を別の形式に変換することも簡単であるため、デコード ステップでこれらのステートメントを表現するために両方の方法の間で変換できます。ただし、どちらの形式が実行速度にどの程度影響するかはわかりません。
2 つのオペコードを 1 つに結合する
ここで、ADD_RRR (レジスターの R) とデータをレジスターにロードするための LOAD があるとします。
これら 2 つのオペコードを使用して、コード全体で常にこのような構成を使用できます...または、それらを ADD_RMR (メモリの M) という名前の単一の新しいオペコードに結合できます。
データ型とオペコード
ネイティブ型として 16 ビット整数と 32 ビット整数があるとします。レジスタは 32 ビットなので、どちらのデータ型にも適合します。2 つのレジスタを追加すると、データ型をパラメーターにすることができます。
たとえば、符号付き整数と符号なし整数についても同じことが言えます。そうすれば、ADD は 1 バイトの短いオペコードになり、別のバイト (または単に 4 ビット) が VM にレジスタの解釈方法を伝えます (レジスタは 16 ビットまたは 32 ビットの値を保持しますか)。または、型エンコーディングを破棄して、代わりに 2 つのオペコードを使用できます。
どちらもまったく同じだと言う人もいるかもしれません.16ビットのオペコードとして最初の方法を解釈するだけでうまくいきます. はい、しかし非常にナイーブなインタープリターは、かなり異なって見えるかもしれません。たとえば、オペコードごとに 1 つの関数があり、switch ステートメントを使用してディスパッチする場合 (最適な方法ではなく、関数呼び出しのオーバーヘッド、switch ステートメントも最適ではないことはわかっています)、2 つのオペコードは次のようになります。
各機能は、特定の種類の追加を中心にしています。ただし、2番目のものは次のようになります。
サブスイッチをメイン スイッチに追加するか、サブ ディスパッチ テーブルをメイン ディスパッチ テーブルに追加します。もちろん、型が明示的であるかどうかに関係なく、インタープリターはどちらの方法でも実行できますが、オペコードの設計に応じて、どちらの方法も開発者にとってよりネイティブに感じられます。
メタ オペコード
より良い名前がないので、そのように呼びます。これらのオペコードは、それ自体ではまったく意味がなく、後続のオペコードの意味を変更するだけです。有名な WIDE 演算子のように:
たとえば、2 番目のケースでは、レジスタは 16 ビット (したがって、より多くのアドレスを指定できます) で、最初のケースでは 8 ビットしかありません。あるいは、そのようなメタ オペコードを持たず、ADD および ADD_WIDE オペコードを持つことはできません。WIDE のようなメタ オペコードは、SUB_WIDE、MUL_WIDE などを持つことを避けます。これは、他のすべての通常のオペコードに常に WIDE を付加できるためです (常に 1 つのオペコードのみ)。不利な点は、オペコードだけでは無意味になることです。それがメタ オペコードであったかどうか、その前にオペコードを常にチェックする必要があります。さらに、VM はスレッドごとに余分な状態を保存し (たとえば、現在ワイド モードであるかどうかに関係なく)、次の命令の後に状態を再度削除する必要があります。CPU にもそのようなオペコードがあります (x86 LOCK オペコードなど)。
適切なトレードオフを見つける方法???
もちろん、オペコードが多いほど、スイッチ/ディスパッチテーブルが大きくなり、これらのコードをディスクまたはメモリで表現するために必要なビットが多くなります (ただし、データが保存されていないディスクにより効率的に格納できる場合があります)。 VM で直接実行できる必要があります)。また、VM はより複雑になり、より多くのコード行が必要になります。一方で、オペコードがより強力になります。複雑な式であっても、すべての式が 1 つのオペコードになるポイントに近づいています。
小さなオペコードを選択すると、VM のコーディングが容易になり、非常にコンパクトなオペコードにつながると思います。一方、単純なタスクを実行するには非常に多くのオペコードが必要になる可能性があり、あまり使用されない式はすべて、オペコードを使用できないため、ある種の(ネイティブ)関数呼び出しになります。
私はインターネット上のあらゆる種類の VM について多くのことを読みましたが、どちらの方向にも適切で公正なトレードオフを実際に行っている情報源はありませんでした。VM の設計は CPU の設計に似ています。オペコードがほとんどなく高速な CPU もありますが、これらの多くも必要です。また、多くのオペコードを持つ CPU があり、非常に遅いものもありますが、同じコードを表現するために必要なオペコードははるかに少なくなります。「オペコードが多いほど良い」CPU が消費者市場を完全に獲得し、「オペコードが少ないほど良い」CPU は、サーバー市場またはスーパー コンピューター ビジネスの一部でのみ生き残ることができるようです。VMはどうですか?
php - 変数インクルードによる APC キャッシング
PHP を使用した APC キャッシングに関する調査を行ったところ、条件付きインクルードが機能しないことがわかりました。お気に入り:
私の質問は、変数インクルードでこれを回避できますか? そのような:
後者のコードは正常に APC キャッシュされるでしょうか?
c - C文字列リテラルはマシンコードにありませんか?
ソースコードがもうないexeの文字列を少し変更する必要があります。Cで書かれていました。
C 文字列リテラルがマシン コードのリストにまったく表示されないように見えることに気付きました。生の ASCII ではなく、utf8/16/32 などではありません。それらはエンコードされているようです.32ビットのオペコードの一部として推測しています. たとえば、コードにc行があったことはわかっています: print("My string"); バイト「m」「y」「」「s」などですが、文字列はまったく表示されないようです。utf8/16/32コーディングでも、1/2/3/4/5でも表示されません各文字間の /6/7/8 バイト (これらすべての組み合わせを確認しました)。
私が理解していることから、リテラルは即時のオペコードにある可能性があり、これらは非バイト整列位置にASCII値の8ビットを持つ可能性があります。私が探すべきオペコードを知っている人はいますか?現時点では、ファイル全体を少しずつシフトしても、文字列のように見えるものはまだ見つかりません。