将多个函数调用折叠为单个函数?

Fold multiple function-calls to single function?

我在考虑一个简单的 SIMD class,它支持重载算术运算符 +-*/
在将其实现为 class 模板以支持不同类型的内部函数时,我注意到有一些可用的函数可以一次执行多个操作(_mm_fmadd_ps 用于乘法和加法)。
我现在想知道是否有一种 相对合理的 方法来仍然使用数学运算符重载
a * b + c -> madd( a , b , c )
而不是使用正常的免费功能
add( mul( a , b ) , c ) -> madd( a , b , c )
使用这些较新的内部函数。

所以我的问题归结为:

  1. 是否可以 多个(独立的)函数调用只调用一个特定函数(一般问题,与 SIMD 无关)?
    • (当代理能够做到这一点时,他们值得吗)?
  2. 如果没有,什么是继续 api 设计 SIMD 容器以提供正常操作并能够更新内在函数的好方法?
    • 同时提供运算符重载和自由函数
    • 放弃运算符重载,只依赖自由函数
  3. 是否允许编译器折叠内在函数以在适当的地方自动使用新内在函数? (当内在函数可用时,将 add( mul( a , b ) , c ) 折叠到 madd( a , b , c ) and/or 已用于所需版本的内在函数)

像这样(您可能想要使用最大优化器设置):

#include <iostream>

template<class Intrinsic>
struct optimised
{
    using type = Intrinsic;

    optimised(type v)
    : _v (v)
    {}

    operator type&() {
        return _v;
    }

    operator const type&() const {
        return _v;
    }

    type _v;
};

// naiive implementation of madd
double madd(double a, double b, double c) {
    std::cout << "madd(" << a << ", " << b << ", " << c << ")" << std::endl;
    return (a * b) + c;
}

struct mul_result
{
    mul_result(const double& a, const double&b)
    : _a(a), _b(b)
    {}

    operator double() const {
        return _a * _b;
    }

    const double &_a, &_b;    
};

double operator+(const mul_result& ab, const double& c)
{
    return madd(ab._a, ab._b, c);
}

mul_result operator*(const optimised<double>& a, const optimised<double>& b)
{
    return mul_result(a, b);
}

using namespace std;

int main()
{
    optimised<double> a = 3, b = 7, c = 2;

    auto x = a * b + c; 
    cout << x << endl;

   return 0;
}

预期输出:

madd(3, 7, 2)                                                                                                                           
23