这个想法与Apple has done in the OpenGL stack有些相似。我希望有一点更普遍。
基本上,我希望针对某些特定情况使用某些代码的专用和优化变体。
换句话说:我给了一个函数的算法/代码(让B = {0,1})
f : B^n -> B^m
现在,我特别针对一个函数的特定情况(预定义 f 的部分输入)
preset : {1..n} -> {0,1,unset}
预定义的数量(∈{0..n})由
给出pn := |preset⁻¹({0,1})|
通常,我们现在获得一个专门的功能
f_preset : B^(n-pn) -> B^m
同样规范地说,我们得到了这个专用函数的代码/算法。当然, f_preset 的代码比 f 的代码快一些,pn> 0.然后,您还可以进一步优化此代码(现在可能存在一些死代码,现在可以解压缩一些循环,可以预先计算某些计算等)。在某些情况下,它可以有显着的改进。
Apple为他们的OpenGL堆栈(从我已阅读/知道的内容)大致做到了这一点:他们试图在运行时找到一个好的预设,然后设置变量不再变化,然后制作专业版的优化版本功能,只使用那个而不是原始功能。
最初,我想到了一种优化某些游戏的物理模拟的方法。我有很多粒子对象和一组粒子类型(在编译时是未知的)。粒子类型是一组属性。粒子类型在加载后是固定不变的。每个粒子对象都是其中一种粒子类型。粒子对象的物理模拟是一些非常重的代码,具有许多分支并且在很大程度上取决于粒子类型。我的想法是为每种粒子类型设置一个优化的物理模拟函数。
在考虑了一下之后,我想进一步了解一下:
我想在运行时自动计算一组这样的预设,并为每个预设维护优化的代码。我想在情况发生变化时自动添加或删除预设。
现在有几个问题:
对于我最初的案例,大多数这些问题已经过时,但我现在对如何以更一般的方式做这件事感兴趣。当然,大多数/所有这些问题都是不可估算的,但我想知道你在多大程度上仍然可以取得好成绩。
这整个主题对于JIT编译器的优化也非常重要。他们是否已经进行了这些优化?到什么程度?
最近有很好的研究工作可以回答我的一些问题吗?或者也许还有一些结果表明以这样一般的方式做这件事太难了?
答案 0 :(得分:0)
在我看来,你问的是partial evaluation。
我实际上对这个概念有点问题,因为它通常用过度学术和过度困难的术语表达。
通常表达的方式是你有一些通用函数F(Islow, Ifast)
,其参数可以在不同的时间采用不同的值。 Islow
参数很少更改,每次调用时Ifast
参数都可以不同。
然后问题是编写某种部分评估函数G(F, Islow) -> F1(Ifast)
,它接受函数F
和Islow
参数,并生成一个新的(更简单的)函数{{1}只接受F1
个参数。
这个问题是1)有人必须编写通用函数Ifast
,2)有人必须编写一般的部分求值程序F
。
对我来说更有意义的是从头开始编写函数G
,即专门为H(Islow) -> F1(Ifast)
编写代码生成器,而不是编写两个函数F1
和{ {1}},尤其是F
很难写的地方。
G
通常比G
更容易编写,H
根本不需要写!结果函数F
通常较小且性能远高于G
,因此这是一个双赢的局面。
当人们编写代码生成器时,这就是他们正在做的事情,而且这是一种非常有效的编程技术。