解码和发送解释与线程解释

zen*_*ngr 12 compiler-construction operating-system interpretation

我试图理解在Decode和调度解释和线程解释中执行程序时的实际差异.

两者的例子都会有所帮助.

我理解Java字节码的工作原理以及汇编语言的工作原理.但是DDI和TI在哪里适合?

上下文:虚拟机:用于系统和进程的多功能平台

Mic*_*inz 20

(注意:我假设"解码和发送"是指基于交换机的解释器.)

运行时基于开关和线程解释器之间的区别基本上是执行的跳转次数.

在基于交换机的解释器中,指令在某个中心位置被解码,并且基于解码的结果,对处理解码指令的代码片段执行跳转.一旦该代码片段完成对指令的解释,它就会跳回到集中解码代码,该代码继续执行下一条指令.这意味着每个解释的指令执行(至少)两次跳转.下面的C代码说明了这样的解释器可能是什么样子:

typedef enum {
  add, /* ... */
} instruction_t;

void interpret() {
  static instruction_t program[] = { add /* ... */ };
  instruction_t* pc = program;
  int* sp = ...; /* stack pointer */
  for (;;) {
    switch (*pc++) {
      case add:
        sp[1] += sp[0];
        sp++;
        break;
        /* ... other instructions */
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在线程解释器中,解码代码不是集中的,而是在处理指令的每段代码的末尾复制.这意味着一旦解释了指令,解释器就会解码下一条指令并立即跳转到它,而不是跳回到某些集中解码代码.实际上在ANSI-C中有效地实现线程代码实际上是不可能的,但是GCC的"计算goto"扩展在这方面非常有效.这是前一个解释器的线程版本:

void interpret() {
  void* program[] = { &&l_add, /* ... */ };
  int* sp = ...;
  void** pc = program;
  goto **pc; /* jump to first instruction */
 l_add:
  sp[1] += sp[0];
  ++sp;
  goto **(++pc); /* jump to next instruction */
  /* ... other instructions */
}
Run Code Online (Sandbox Code Playgroud)

除了保存跳转之外,这样的线程解释器也更有效,因为现代CPU可以更好地预测复制的间接跳转(到下一条指令).Anton Ertl在他的主页上有一些有趣的论文,特别是一本名为"高效口译员的结构与表现"的论文,上面的代码被改编.