我需要一些帮助来优化分段线性传递函数的基于特征的实现(输出值等于输入,但限制为一个范围,在这种情况下为[-0.5,0.5])。下面是我介绍的功能:

typedef float SignalT;
typdedef Eigen::Array<SignalT, Eigen::Dynamic, Eigen::Dynamic> Signal2D;
void ActivateSum(unsigned char const idx, Signal2D::ColXpr& outputSum)
{
    switch (idx)
    {
    case 0U:
        //Threshold
        outputSum = (outputSum >= (SignalT) 0.0).cast<SignalT>();
        break;
    case 1U:
        //Piecewise linear
        outputSum = outputSum.unaryExpr([](SignalT const elem)
        {
            if (elem >(SignalT) 0.5)
                return (SignalT) 0.5;
            else if (elem < (SignalT)-0.5)
                return (SignalT)-0.5;
            else
                return elem;
        }
        );
        break;
    case 2U:
        //Fast Sigmoid
        outputSum *= ((SignalT) 1.0 + outputSum.abs()).inverse();
        break;
    default:
        assert(0);
        throw;
    }
}

我的整个程序在每种切换情况下均花费以下样本示例:
Threshold: 3.3%
Piecewise Linear: 18%
Fast Sigmoid: < 0.1%

快速S型曲线很少使用,但分段线性情况应与阈值情况一样频繁发生(尽管我不知道如何使用Visual Studio进行测量)。所以在我看来,我在分段线性一元表达式中花费了很多时间,并且想知道是否存在另一种方法来实现Eigen中的功能,也许是通过使用一些内置方法来提高速度。这是一个非常简单的传递函数,因此它实际上应该在计算上非常便宜-我的猜测是,由于我的自定义Lambda导致的成本不佳而与优化无关,这比其他任何事情都重要。

有什么想法吗?

编辑:到目前为止,由于Leeor的回答,我已经提出了这个建议:
case 1U:
    //Piecewise linear
    outputSum = outputSum.max((SignalT)-0.5).min((SignalT)0.5);
    break;

最佳答案

如果您现有的代码尚未进行编译,请使用FPU最大和最小指令。

    outputSum = outputSum.unaryExpr( [] (SignalT elem)
    {
        return std::fmax( -0.5f, std::fmin( 0.5f, elem ) );
    }

Eigen可能已经内置了这样的操作,但是浏览文档并没有发现任何问题。

关于c++ - 如何在Eigen中实现高性能的分段线性传递函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19783947/

10-10 23:42