特征值:有效地将矩阵求值的输出存储在原始指针中

不来梅

我正在使用一些传承许多原始指针的旧式C代码。要与代码交互,我必须传递以下形式的函数:

const int N = ...;

T * func(T * x)  {
    // TODO Put N elements in x
    return x + N;
}

该函数应将结果写入的位置x,然后返回x

在内部,在此功能中,我广泛使用Eigen进行一些计算。然后,使用Map该类将结果写回到原始指针一个模仿我在做什么的简单例子是这样的:

const int N = 5;
T * func(T * x)  {

    // Do a lot of operations that result in some matrices like
    Eigen::Matrix<T, N, 1 > A = ... 
    Eigen::Matrix<T, N, 1 > B = ... 

    Eigen::Map<Eigen::Matrix<T, N, 1 >> constraint(x);
    constraint = A - B;

    return x + N;
}

显然,内部发生了很多复杂的事情,但这就是要点...用Eigen进行一些计算,然后使用Map该类将结果写回到原始指针。

现在的问题是,当我使用Callgrind分析此代码,然后使用KCachegrind查看结果时,这些行

constraint = A - B;

几乎总是瓶颈。这是可以理解的,因为此类行可能/正在做三件事:

  1. 构造Map对象
  2. 执行计算
  3. 将结果写入指针

因此可以理解,这条线的运行时间最长。但是我有点担心,也许我在以某种方式在将数据写入原始指针之前在那一行进行了额外的复制。

那么,是否有更好的方法将结果写入原始指针?还是我应该使用的成语?

在我的脑海中,我想知道使用placement new语法是否可以在这里给我带来任何好处。

注意:此代码是关键任务,应实时运行,因此我确实需要从中挤出每一分的速度。例如,从0.12秒到0.1秒的运行时间获得此调用对我们来说将是巨大的。但是,由于我们一直在调整内部计算中使用的模型,因此代码易读性也是一个巨大的问题。

加格尔

这两行代码:

Eigen::Map<Eigen::Matrix<T, N, 1 >> constraint(x);
constraint = A - B;

本质上由Eigen编译为:

for(int i=0; i<N; ++i)
  x[i] = A[i] - B[i];

由于显式展开和显式矢量化(均取决于T),因此实际情况更加复杂,但这实际上就是事实。因此,该Map对象的构造本质上是无操作的(任何编译器都对其进行了优化),并且没有,这里没有多余的副本。

实际上,如果您的探查器能够告诉您瓶颈在于此简单表达式上,则很可能意味着该代码段尚未内联,这意味着您未启用编译器优化标志(例如-O3gcc / clang) 。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章