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

Fold multiple function-calls to single function?

本文关键字:单个 函数 折叠 函数调用      更新时间:2023-10-16

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

所以我的问题归结为:

  1. 是否可以链接多个(独立的)函数调用以仅调用一个特定函数(一般问题,与 SIMD 无关)?
    • (当代理能够做到这一点时,他们值得吗)?
  2. 如果没有,那么关于 SIMD 容器的 API 设计以提供正常操作并能够更新内部函数的好方法是什么?
    • 同时提供操作员过载和自由功能
    • 摒弃操作员过载,仅依靠自由功能
  3. 是否允许编译器折叠内部函数以在适当的情况下自动使用新内部函数?(当内部函数可用和/或已用于所需版本的内部函数时,add( mul( a , b ) , c )折叠以madd( a , b , c ))

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

#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