如何根据编译时参数使用内联函数的不同重载?

发布于 2024-10-17 19:40:01 字数 311 浏览 2 评论 0原文

我有一个性能关键的内联函数,inline T func(T a, T b, int p)。如果已知 p 为零,则可以对其进行相当多的优化。但是,我不能使用“如果”来惩罚所有其他情况。我想要的是仅优化我在编译时知道 p 为零的函数。有没有一种干净的方法可以做到这一点,也许使用模板魔法?

编辑

我不能使用不同名称的函数/不兼容的重载(我不知道如何正确表达),因为代码的级别非常低。另一个/未来的处理器很可能有不同的优化机会。因此,通过将所有低级内容限制在一个函数签名中,我的代码只需要重新编译即可使用任何类型的优化。

I have a performance critical inline function, inline T func(T a, T b, int p). It can be optimized quite a bit, if p is known to be zero. However, I can't use an 'if' and penalize all the the other cases. What I want is to optimize the function only of I know at compile-time that p is zero. Is there a clean way to do that, maybe using template magic?

EDIT

I can't use differently named function/incompatible overloads (I don't know ho to express that correctly) since the code is very low level. It is very likely, that different optimization opportunities are available on another/future processors. Thus by confining all that low level stuff in one function signature, my code only needs to be recompiled to use any type of optimization.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沉睡月亮 2024-10-24 19:40:01

可以使用模板。看看Boost enable_if,它有很好的解释和使用示例

it's possible using templates. have a look at Boost enable_if, it has good explanation and usage examples

三生殊途 2024-10-24 19:40:01

如果 Boost 不能满足要求,这里还有另一种方法。不过,p 参数必须是调用中的文字。

#include <iostream>

// Template this on the functions if you wanted this type templated:
typedef float T; 

template<int P>
struct Wrapper {
    static T func(T a, T b) {
        std::cout << "general case (p="<< P << ")\n";
        return (a+b)*P;
    }
};

// Template specialisation for P=0
template <>
struct Wrapper<0> {
    static T func(T a, T b) {
        std::cout << "p=0 case\n";
        return 0;
    }
};

#define func(A, B, P) \
    Wrapper<P>::func(A, B)

int main() {
    func(1,2,0);
    func(1,2,345);
}

模板专门化在函数上是不可能的,因此需要包装类。

Here's another way of doing it, if Boost doesn't satisfy. The p parameter must be a literal in the call, though.

#include <iostream>

// Template this on the functions if you wanted this type templated:
typedef float T; 

template<int P>
struct Wrapper {
    static T func(T a, T b) {
        std::cout << "general case (p="<< P << ")\n";
        return (a+b)*P;
    }
};

// Template specialisation for P=0
template <>
struct Wrapper<0> {
    static T func(T a, T b) {
        std::cout << "p=0 case\n";
        return 0;
    }
};

#define func(A, B, P) \
    Wrapper<P>::func(A, B)

int main() {
    func(1,2,0);
    func(1,2,345);
}

Template specialisation isn't possible on functions, hence the need for the wrapper class.

×眷恋的温暖 2024-10-24 19:40:01

GCC 有一个 __builtin_constant_p 函数;更多信息请参见 GCC 文档。我相信您能够

inline T func(T a, T b, int p)
{
    if ( builtin_constant_p(p) && p==0 )
        // special case
    else
        // fallback
}

在没有任何性能损失的情况下获得。

GCC has a __builtin_constant_p function; more information in the GCC docs. I believe you'd be able to have

inline T func(T a, T b, int p)
{
    if ( builtin_constant_p(p) && p==0 )
        // special case
    else
        // fallback
}

without any performance loss.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文