使编译的二进制文件以本机速度完美运行,而无需从另一个系统上的源代码重新编译?

Kar*_*arl 3 compiler-construction virtualization native constraints aot

我知道很多人,乍一看这个问题,可能会立即喊出"Java",但不,我知道Java的品质.请允许我先说明我的问题.

通常,当我们希望程序在系统上以本机速度运行时,无论是Windows,Mac OS X还是Linux,我们都需要从源代码进行编译.如果要在系统中运行其他系统的程序,则需要使用虚拟机或仿真器.虽然这些工具允许您在非本机操作系统上使用所需的程序,但它们有时会出现性能和故障问题.

我们还有一个名为"JIT Compiler"的新编译器,编译器在执行之前将字节码程序解析为本机机器语言.使用JIT Compiler,性能可能会有很大提升,但性能仍然与在本机系统上运行它的性能不同.

Linux上的另一个程序WINE也是在Linux系统上运行Windows程序的好工具.我已经尝试过运行Team Fortress 2,并试着尝试一些设置.在1280 x 1024的中高设置下,我在Windows上获得了~40 fps.在Linux上,我需要将所有内容都调低至1280 x 1024以获得~40 fps.但有两件值得注意的事情:

  1. 无论我将其设置为低还是高,多边形模型设置似乎都不会影响帧速率.
  2. 当存在后处理效果或某些需要操纵当前帧的绘制像素的特殊效果时,帧速率将降至10-20 fps.

从这一点来看,我可以看到正常的多边形渲染很好,但是当涉及需要图形卡的新渲染方法时,它会慢下来爬行.

无论如何,这个问题相当理论化.有什么我们可以做的吗?我看到WINE可以运行STEAM和Team Fortress 2.虽然存在缺陷,但它们可以在较低的设置下运行.或许,我也应该问," 是否有可能将系统上的整个程序转换到另一个系统而无需从源代码重新编译并获得原生速度? "我看到我们也有AOT编译器,是否可以将它用于某些东西像这样?或者有如此多的限制(例如DirectX调用或软件架构的差异)使得无法在本机速度下运行的系统程序完美无缺?

dth*_*rpe 6

在不重新编译的情况下以本机速度在多个系统上运行相同编译代码体的第一步是选择一个处理器指令集并丢弃所有其他系统.如果选择Intel,则必须抛弃ARM,MIPS,PowerPC等,因为一个架构的本机机器代码指令对于其他处理器来说完全无法理解.

好.因此,现在的任务是在本机速度下在多个系统(均使用相同的处理器体系结构)上运行相同的编译本机代码体,而无需重新编译.基本上,您希望在同一硬件上的不同操作系统下运行相同的代码.

如果硬件是相同的,唯一的区别是操作系统,那么简单的答案是肯定的,如果您可以编写代码而无需调用操作系统,则可以执行此操作.没有内存分配.无控制台输出.没有文件I/O. 没有网络I/O. 没有什么好玩的.

此外,您的代码必须以这样的方式编写,即代码不需要地址重定位修正,因为每个操作系统都有不同的方式来表示可重定位代码.一种方法是将代码安排在磁盘上,就像在内存中一样,包括保留用于可写数据的空间(全局变量,堆栈和堆).然后,您需要做的就是运行代码,将文件字节复制到预定义基址的内存中,然后跳转到起始地址.

MSDOS .com可执行文件格式至少自1981年以来一直在这样做,而CP/M早在此之前.

然而,MSDOS当时没有今天的病毒扫描程序可以应对.当主机操作系统以外的任何人将文件数据加载到内存并尝试执行该内存时,病毒扫描程序会非常兴奋.因为,你知道,这正是病毒的作用.

由于每个操作系统都有自己的可执行文件格式,因此您还需要弄清楚如何在所有这些不同的操作系统上将"无瑕疵"的本机代码块存入内存.您至少需要为每个要运行本机代码块的操作系统编译一个程序加载器.当您为要定位的每个OS编写程序加载程序时,您还可以定义自己的文件I/O函数映射到OS本机等效项,以便您的本机代码块可以在任何系统上执行文件I/O. 同样适用于控制台I/O或图形输出.

哦等等 - 这正是WINE所做的.

这也是为什么你在WINE中看到的帧速率比主机操作系统中的相同操作低得多的原因 - WINE正在将Win32 GDI图形调用转换为本机主机操作系统(Linux - > XWindows)提供的内容,并且没有'在确切的函数匹配或存在操作语义不匹配的情况下(通常情况下),WINE必须自己实现所有功能,有时需要付出很大的代价.

但鉴于IDE驱动器,USB设备和BIOS功能等标准化硬件无处不在,您可能不需要将自己的便携式API映射到操作系统内置的任何内容上.只需编写一些代码即可.对IDE设备执行文件I/O,使用VESA BIOS功能进行图形输出.如果您稍微抽象一下代码,您可以支持多种硬件,并根据您在运行时找到的硬件选择适当的函数指针.

然后,您可以在任何系统(使用一个特定的处理器体系结构)上以原生速度真正运行本机代码块,而无需重新编译.

哦等等 - 你刚刚编写了自己的操作系统.;>