优化复合std ::函数

时间:2011-07-21 14:50:04

标签: c++ optimization functional-programming c++11 mathematical-optimization

是否可以优化一系列“粘合”std::function和/或是否有任何尝试执行此操作的实现?

我的意思是最容易以数学方式表达:说我想制作一个函数函数std::function

f(x,y,z) = x^2 * y^3 * z^4
g(x,y,z) = f(x,y,z) / (x*y^2)

是否有一种方法可以让STL /编译器实现者优化掉算术部分是调用g的函数对象,是从f的函数对象创建的?

这将是函数的一种符号简化,但因为它是std::function,所以必须在机器级别上发现它。

由于这是一种优化,需要时间,而且可能不是免费的(在时钟周期和/或内存中),标准可能不允许这样做?它倾向于非常接近通常通过VM运行的语言。 (我认为LLVM不仅仅是Java,还有运行时优化)。

编辑:为了使讨论“更有用”,这里是一个简短的代码片段(我理解lambda不是std::function,但lambda可以存储在std::function中,所以假设auto以下std::function<T>表示Tauto f = [](const double x, const double y, const double z){ return x*x*y*y*y*z*z*z*z; }; auto g = [](const double c, const double y, const double z){ return f(x,y,z)/(x*y*y); }; 将完全表达我的意思:

g

“普通”编译器会使double g(const double x, const double y, const double z){ return x*x*y*y*y*z*z*z*z/(x*y*y); } 等同于

std::function

虽然优化的double g( const double x, const double y, const double z){ return x*y*z*z*z*z; } 可以实现(数学上和其他方面都是正确的!):

{{1}}

请注意,虽然我在这里谈论的是数学函数,但是对于一般意义上的函数可以进行类似的转换,但这需要更多的内省,这意味着开销。

在设计数学和物理模拟时,我可以看到这一点非常重要,其中将现有库函数合成到用户案例函数中的一般性,通过所有常用的数学简化,可以提供一种表达性但性能良好的计算软件的好方法

2 个答案:

答案 0 :(得分:4)

这就是您将优化留给编译器的原因。由于FP不精确,它们在代数上是等价的但等价。你的两个版本的g会产生微妙的不同答案,如果在内循环中调用,这可能非常重要 - 更不用说x,y,z为0时的行为差异。

其次,由于function的内容在运行时是未知的,因此编译器无法执行此类优化,因为它没有所需的数据。

答案 1 :(得分:1)

允许编译器在特定允许的情况下进行优化,或者如果优化代码表现为“好像”它是未经过优化的代码。

在这种情况下,xy不仅会更改结果,但如果f溢出,或者数据类型为浮点或用户定义,则结果可能会更改为这种优化的结果。因此,我怀疑在实践中你永远不会看到它发生,并且必须(如果可能的话)在编译时组合一个组合函数(大概是使用模板)。