在我的项目中,我有一些像这样的抽象层:
Vector3 normalizeVector(Vector3 v);
Vector3 vectorMultiplyMatrix(Vector3 v, Matrix3 m);
这只是平台特定数学库(如 DirectXMath)的“代理”函数。
我的问题是如何降低这些层的成本?通过使所有这些函数内联,是否会完全消除调用它们而不是直接调用特定于平台的函数的成本?
谢谢
在我的项目中,我有一些像这样的抽象层:
Vector3 normalizeVector(Vector3 v);
Vector3 vectorMultiplyMatrix(Vector3 v, Matrix3 m);
这只是平台特定数学库(如 DirectXMath)的“代理”函数。
我的问题是如何降低这些层的成本?通过使所有这些函数内联,是否会完全消除调用它们而不是直接调用特定于平台的函数的成本?
谢谢
添加一个新的抽象级别(代理、外观等)的成本可以忽略不计。您将数据传递给它们的方式可能会给您带来麻烦,尤其是在使用复杂的对象、容器等时。
Vector3 normalizeVector(Vector3 v);
Vector3
在每次调用时创建传递对象的副本。如果您遇到性能问题,请避免通过将按值传递更改为按const
引用传递来创建副本:
Vector3 normalizeVector(const Vector3& v);
这个函数的这个新原型表示:“我需要一个对我将使用但不会更改的现有有效Vector3
对象的引用”。
除非您真的遇到性能问题,否则不要优化您的代码。过早的优化一直是邪恶的,而且永远都是。
暴露函数体将使编译器有机会通过内联消除函数调用。
它是否真的接受它取决于它的内部启发式:内联可能会扩大生成代码的整体大小,使其对缓存不太友好,并最终否定消除调用的好处。
有一些特殊的关键字(例如VC++ 下的__forceinline)可以用来覆盖编译器的成本/收益分析,但编译器通常比程序员更正确地做出这些决定!
使用profile-guided optimization可以帮助编译器根据程序的实际使用模式做出更好的优化决策,包括哪些函数“热”到足以内联,哪些函数“冷”并且应该不理会。
要记住的一种特别强大的技术是模板元编程。这个想法是将尽可能多的计算推到编译时。