c++ - 使用 JIT 设计虚拟机

标签 c++ vm-implementation

我正在开发一种脚本语言,它可以为自己的虚拟机编译,这是一种简单的语言,具有处理某种数据的指令,例如 vector floats 等等.. 内存单元以这种方式表示:

struct memory_cell
{
    u32 id;
    u8 type;

    union
    {
        u8 b; /* boolean */
        double f; /* float */
        struct { double x, y, z; } v; /* vector */
        struct { double r, g, b; } c; /* color */
        struct { double r, g, b; } cw; /* color weight */
        struct { double x, y, z; } p; /* point variable */
        struct { u16 length; memory_cell **cells; } l; /* list variable */
    };  
};

指令是通用的,能够处理许多不同的操作数。例如

ADD dest, src1, src2

可以使用 float 、 vector 、点、颜色根据操作数设置正确的目的地类型。

主执行周期只是检查指令的操作码(这是一个包含 union 体的结构,用于定义任何类型的指令)并执行它。我使用了一种简化的方法,其中我没有寄存器,只有一大堆存储单元。

我想知道 JIT 是否可以帮助我获得最佳性能以及如何实现它。

正如我所说,迄今为止最好的实现是这样的:

 void VirtualMachine::executeInstruction(instr i)
 {
     u8 opcode = (i.opcode[0] & (u8)0xFC) >> 2;

     if (opcode >= 1 && opcode <= 17) /* RTL instruction */
     {
        memory_cell *dest;
        memory_cell *src1;
        memory_cell *src2;

        /* fetching destination */
        switch (i.opcode[0] & 0x03)
        {
            /* skip fetching for optimization */
            case 0: { break; }
            case MEM_CELL: { dest = memory[stack_pointer+i.rtl.dest.cell]; break; }
            case ARRAY_VAL: { dest = memory[stack_pointer+i.rtl.dest.cell]->l.cells[i.rtl.dest.index]; break; }
            case ARRAY_CELL: { dest = memory[stack_pointer+i.rtl.dest.cell]->l.cells[(int)i.rtl.dest.value]; break; }
        }

     /* omitted code */

     switch (opcode)
     {
         case ADD:
         {
             if (src1->type == M_VECTOR && src2->type == M_VECTOR)
             {
                 dest->type = M_VECTOR;
                 dest->v.x = src1->v.x + src2->v.x;
                 dest->v.y = src1->v.y + src2->v.y;
                 dest->v.z = src1->v.z + src2->v.z;
              }

      /* omitted code */

尝试jit编译容易/方便吗?但我真的不知道从哪里开始,这就是为什么我要问一些建议。

除此之外,我在开发它时还有其他建议吗?

这个虚拟机应该足够快来计算光线追踪器的着色器,但我还没有做任何类型的基准测试。

最佳答案

在编写 JIT(“即时”)编译器之前,您至少应该考虑如何编写“超前”编译器。

也就是说,给定一个由 VM 指令组成的程序,您将如何生成一个由 x86(或其他)指令组成的程序,它的功能与原始程序相同?您将如何优化不同指令集和同一架构的不同版本的输出?您给出的示例操作码具有相当复杂的实现,那么哪些操作码可以通过仅发出执行该工作的代码来“内联”实现,哪些可以通过发出对某些共享代码的调用来实现?

JIT 必须能够做到这一点,而且它还必须在 VM 运行时做出决定,决定它对哪些代码执行操作,何时执行,以及它如何表示 VM 指令和 native 指令的混合结果说明。

如果您还不是装配师,那么我不建议您编写 JIT。这并不是说“永远不要这样做”,而是您应该在认真开始之前成为一名集会骑师。

另一种方法是编写一个非 JIT 编译器,将您的 VM 指令(或原始脚本语言)转换为 Java 字节码或 LLVM,正如 Jeff Foster 所说。然后让该字节码的工具链完成困难的、依赖于 CPU 的工作。

关于c++ - 使用 JIT 设计虚拟机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1812395/

相关文章:

c - 实现 VM 的教程/资源

c++ - 为 C 的子集实现基于堆栈的虚拟机

c++ - 如何分隔数组中的奇数和偶数?

c++ - 如何在一个函数中访问另一个函数中的变量?

c++ - g++ std::chrono 断言中断

multithreading - Java虚拟机如何实现 "happens-before"内存模型?

c++ - VM解释器-权衡性能的优点和缺点:较大的指令集/调度循环

c++ - asm.js 规范中提到的 c/c++ 虚拟机是什么

c++ - wxwidget wxRichTextCtrl编译结果在ld : symbol(s) not found

android - 将 jlong​​ 转换为 long 是否安全?