【问题标题】:dynamic code compilation动态代码编译
【发布时间】:2010-11-29 08:12:18
【问题描述】:

我正在开发一个渲染迭代分形系统的程序。我想添加一个功能,让人们可以定义自己的迭代过程,并编译该代码以使其高效运行。

我目前不知道如何执行此操作,并希望获得有关阅读内容以了解如何执行此操作的提示。

主程序是用C++编写的,我对C++很熟悉。事实上,考虑到大多数情况,我知道如何将其转换为可以实现目标的汇编代码,但我不知道如何采取额外的步骤将其转换为机器代码。如果可能的话,我想动态编译代码,就像我相信许多游戏系统模拟器的工作方式一样。

如果不清楚我在问什么,请告诉我,以便我澄清。

谢谢!

【问题讨论】:

  • 哪个操作系统?您是在问如何编写/构建用户定义的代码,如何编译它,或者编译后如何加载它?
  • 目前只兼容Windows。我在问如何将我定义的脚本语言编译成机器代码。下面每个人都提到的 LLVM 看起来是解决方案,但我仍在阅读如何使用它。
  • 您应该研究 HLSL,它是针对此问题的特定领域解决方案。

标签: c++ compilation dynamic-compilation


【解决方案1】:

要动态编译的例程是否需要使用任何特定语言。如果该问题的答案是“是的,它必须是 C++”,那么您可能就不走运了。 C++ 是在线重新编译的最糟糕的选择。

应用程序的动态部分(分形迭代器例程)是否是主要的 CPU 瓶颈?如果您负担得起使用未经编译的语言,您可能会为自己省去很多麻烦。 Lua 和 JavaScript 都是经过高度优化的解释性语言,它们的运行速度只比原生编译代码慢几倍。

如果您确实需要将动态功能编译为机器代码,那么您最好的选择可能是使用 clang/llvm. clang 是 Apple(和其他一些人)正在开发的 C/Objective-C 前端使在线,动态重新编译表现良好。 llvm 是 clang 用于从可移植字节码转换为本机机器码的后端。请注意,clang 目前不支持大部分 C++,因为这是一种很难正确处理的语言。

【讨论】:

  • 效率是一个巨大的问题,因为 IFS 可能需要每个像素 1,000 到 100,000 次迭代,因此使每次迭代运行得更快一点会对整个应用程序产生巨大影响。这就是为什么我需要编译脚本。我目前正在研究 LLVM。
【解决方案2】:

一些 CPU 仿真器将机器代码视为字节码,并且它们执行 JIT 编译,几乎就像它是 Java 一样。这是非常高效的,但这意味着开发人员需要为每个运行其模拟器的 CPU 和每个模拟的 CPU 编写一个编译器版本。

这通常意味着它仅适用于 x86,并且对于任何想要使用不同的东西的人来说都很烦人。

他们还可以将其转换为 LLVM 或 Java 字节码或 .Net CIL,然后进行编译,这也可以。

在你的情况下,我不确定这种事情是最好的方法。我认为我会通过使用动态库来做到这一点。创建一个应该包含“插件”的目录并让用户自己编译。让您的程序扫描目录并加载它找到的每个 DLL 或 .so。

这样做意味着您花费更少的时间编写代码编译器,而将更多的时间用于实际完成工作。

【讨论】:

    【解决方案3】:

    如果您可以用 C(不是 C++)编写动态扩展,您可能会发现 Tiny C Compiler 很有用。它在 LGPL 下可用,与 Windows 和 Linux 兼容,它是一个小型可执行文件(或库),大小约为 100kb,用于预处理器、编译器、链接器和汇编器,所有这些都非常快。当然,这样做的缺点是它无法与 GCC 获得的优化相提并论。另一个潜在的缺点是它仅适用于 X86 AFAIK。

    如果您确实决定编写程序集,TCC 可以处理——the documentation 说它支持类似气体的语法,并且确实支持 X86 操作码。

    TCC 还完全支持 ANSI C,并且几乎完全符合 C99。

    话虽如此,您可以将 TCC 作为可执行文件包含在您的应用程序中,也可以使用 libtcc(网上没有太多关于 libtcc 的文档,但可以在源代码包中找到它)。无论哪种方式,您都可以use tcc to generate dynamic or shared libraries 或可执行文件。如果你走动态库路线,你只需在其中放入一个Render(或其他)函数,并在其中添加dlopen或LoadLibrary,然后调用Render最终运行用户设计的渲染。或者,您可以制作一个独立的可执行文件并popen 它,并通过独立的stdin 和stdout 进行所有通信。

    【讨论】:

      【解决方案4】:

      由于您正在生成要在屏幕上显示的像素,您是否考虑过将 HLSL 与动态着色器编译一起使用?这将使您能够访问专为此类事情设计的 SIMD 硬件,以及直接内置于 DirectX 中的动态编译器。

      【讨论】:

      • 我确实考虑过,但我希望支持可变精度,而大多数显卡只支持 32 位精度。我可能会做的是,如果他们将其设置为 32 位精度,我将使用 HLSL,否则我不会。但我确实计划支持无限精度的程序。当然,我可以在显卡上模拟更高的精度,但我也不能依赖每个人都拥有具有良好处理能力的显卡。我不确定集成显卡是否真的会比其耦合的 CPU 具有更高的吞吐量。
      • 对于他们的设计目标——对庞大的浮点数数组进行线性变换——GPU 肯定比 CPU 快,因为专用硬件、宽 ALU 和深管道。但你是对的,除了 32 位精度之外,它们没有多大用处。
      【解决方案5】:

      LLVM 应该可以做你想做的事。它允许您以面向对象的方式形成您想要编译的程序的描述,然后它可以在运行时将该程序描述编译成本机机器代码。

      【讨论】:

        【解决方案6】:

        Nanojit 是您想要的一个很好的例子。它从中间语言生成机器代码。它是 C++,体积小且跨平台。我没有很广泛地使用它,但我喜欢只是为了演示而玩弄。

        【讨论】:

          【解决方案7】:

          将代码吐出到一个文件中,编译为动态加载的库,然后加载并调用它。

          【讨论】:

            【解决方案8】:

            您是否有理由不能使用基于 GPU 的解决方案?这似乎是在为一个人尖叫。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-06-10
              • 2016-08-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-07-27
              • 1970-01-01
              相关资源
              最近更新 更多