首页 > 解决方案 > 如何使用 Eigen 提高我的性能?(包括示例代码)

问题描述

在以下函数中,我的矩阵数学是否有任何效率过低的地方?我在 Visual Studio 中启用了优化,并且正在构建 64 位发布模式。我在这里(750X350)提供了相当大的矩阵,但我的表现似乎仍然很慢。

void NeuralNetwork::backward(Eigen::MatrixXf back, float learningRate)
{
    std::vector<Eigen::MatrixXf> dedw;
    std::vector<Eigen::MatrixXf> delta;

    int nLayers = layers.size();

    int dIt = 0;
    for (int i = nLayers -1;i > 0; i=i-1)
    {
        Eigen::MatrixXf deltai;
        logger->LogVerbose("--------","Back", i,"---------");
        if (i == (nLayers - 1))
        {
            deltai.noalias() = back.cwiseProduct(dSigmoid(X[i]));
            delta.push_back(deltai);
            dIt++;

        }
        else
        {
            logger->LogVerbose("W", i);
            deltai.noalias() = (W[i].transpose() * delta[dIt - 1]).cwiseProduct(dSigmoid(X[i]));
            delta.push_back(deltai);
            dIt++;
        }
        Eigen::MatrixXf dedwi;
        dedwi.noalias() = delta[dIt - 1] * X[i - 1].transpose();
        dedw.push_back(dedwi);
        logger->LogVerbose("dedw", dIt - 1, dedw[dIt - 1]);

        Eigen::MatrixXf WiNew;
        WiNew.noalias() = W[i - 1] - learningRate * dedw[dIt - 1];
        W[i-1] = WiNew;
        logger->LogVerbose("W", i - 1);
        logger->LogVerbose(W[i - 1]);

        Eigen::MatrixXf BiNew;
        BiNew.noalias() = B[i - 1] - learningRate * delta[dIt - 1];
        B[i-1] = BiNew;
        logger->LogVerbose("B", i - 1);
        logger->LogVerbose(B[i - 1]);


    }
}

标签: c++eigen

解决方案


避免在对性能敏感的代码中进行内存密集型操作。

  1. 永远不要按价值传递“大论据”。

例如

void NeuralNetwork::backward(Eigen::MatrixXf back, float learningRate)

应该是

void NeuralNetwork::backward(const Eigen::MatrixXf& back, float learningRate)

这避免了在函数中一次又一次地复制构造参数。

  1. 避免在函数内部复制。您推送到临时deltadedw向量矩阵。你可能想像这样移动它们:delta.push_back(std::move(deltai));
  2. 重用分配的内存。您可能可以重用deltadedw工作空间向量。即使尽量减少不必要的分配 - 解除分配。如果您不需要上一次调用中的元素 - 只需清除它们即可。

这些将是首先要做的事情。最后——简介

我会用它perf record来分析程序中的瓶颈。挤出更多性能的最佳方法是修复最大的瓶颈。在这一点上,你不知道你最大的瓶颈在哪里。所以简介,简介,简介。


推荐阅读