这个想法有点类似于Apple has done in the OpenGL stack。我想要更一般一点。确定在什么情况下什么变量是常数
基本上,我想对某些特定情况有一些代码的专门和优化的变体。
换句话说:我已给定了算法/代码的函数(让B = {0,1})
f : B^n -> B^m
现在,我通过特殊的功能的特定情况(其预先定义的一部分的˚F输入)
preset : {1..n} -> {0,1,unset}
predefinitions(∈的量{0..N})然后通过
pn := |preset⁻¹({0,1})|
给定
规范地,我们现在得到一个专业功能
f_preset : B^(n-pn) -> B^m
同时规范地,我们得到这个特殊函数的代码/算法。当然,f_preset的代码将比pk> 0的f更快。然后,您还可以进一步优化此代码(现在可能会有一些死代码,现在可能会有一些循环解压缩,一些计算可以预先计算等)。在某些情况下,它可以有显着的改进。
苹果公司为他们的OpenGL堆栈做了大致的工作(从我已经阅读/了解的内容):他们试图在运行时找到一个好的预设,然后为不会改变的变量设置一个优化版本专门的功能,只使用那个而不是原来的功能。
最初,我想到了一种方法来优化一些自己的游戏的物理模拟。在那里我有很多粒子对象和一组粒子类型(这在编译时是未知的)。粒子类型是一组属性。一旦它们被加载,粒子类型是固定的并且是恒定的。每个粒子对象都是其中一种粒子类型。粒子对象的物理模拟是许多分支代码的非常重要的和平,并且非常依赖于粒子类型。我的想法是现在为每个粒子类型都有一个优化的物理模拟功能。
思考了一下这个之后,我想去远一点:
我希望在运行时自动计算一组这样的预设和维护每个优化的代码。我想在环境发生变化时自动添加或删除预设。
现在有几个问题:
- 有一种简单的方法来计算一个好的预置?我怎么知道哪些变量对于一个给定的情况是不变的?
- 有没有简单的方法来检查一个预设有多好? “好”是指所得优化代码的性能。
- 如何比较两种算法/代码的性能?通过一些启发式?或通过随机输入测试?
- 应该有多少预设(和优化的代码变体)?所有功能的固定限制?或者每个功能都有所不同?它甚至可能取决于当前的计算机状态?
- 如何维护不同的优化代码变体?一个包装函数大约f它自动选择最佳优化变体似乎不是很好,因为这可能不是那么容易检查将需要每一个电话。这个问题的解决方案也可能与如何找到好的预设集合/数量有关。 (在粒子类型的情况下,优化的代码将与粒子类型一起附加/保存,粒子类型的数量也定义了预设的数量。)
对于我的第一种情况,大多数这些问题有点过时了,但我现在对如何以更一般的方式做到这一点非常感兴趣。当然,大多数/所有这些问题都是不可计算的,但我想知道你在多大程度上仍然可以获得好的结果。
这整个主题对于JIT编译器的优化也非常重要。他们是否已经进行了这种优化?到什么程度?
有没有很好的最近的研究工作,回答我的一些问题?或者,也许还有一些结果表明,以这种普遍的方式做这件事实在太难了?
苹果在那里做了什么是一个非常明智的技术,已经在图形和其他领域使用了数十年(但从未教过,我知道)。例如,贝尔实验室* Blit *终端(http://doc.cat-v.org/bell_labs/blit/)使用这种技术。他们可以生成机器语言并在堆栈上运行它。 – 2010-05-11 14:27:22