如何在特征中实现高性能分段线性传递函数
How do I implement a high-performance piecewise linear transfer function in Eigen?
我需要一些帮助来优化分段线性传递函数的基于特征的实现(输出值等于输入,但上限为一个范围,在本例中为 [-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%
快速 sigmoid 很少使用,但分段线性情况应该与阈值情况一样频繁地出现(尽管我不知道如何使用 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可能已经内置了这样的操作,但看一眼文档并没有发现任何东西。
可能是分支预测,您的 if 条件会创建一个复杂的数据依赖控制流,多个返回站点可能使其难以优化。
也许像这样的三元运算符会消除分支:
return (elem>0? 1 : -1) * (std::min(std::abs(elem),0.5));
(确保你使用支持浮点数 ABS 的 LIB,我认为 CMaAh 应该没问题)。
查看编译器是否通过条件移动以这种方式发出分支较少的代码。
相关文章:
- 分段故障(堆芯转储)矢量
- 数组的指针从不分段故障
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 如何在特征中实现高性能分段线性传递函数