c++ - 随着计算的进行,我的 C++ 程序变慢了

标签 c++ neural-network

我用 C++ 编写了一个神经网络程序来测试一些东西,我发现我的程序随着计算的进行而变慢。由于这种现象有些我以前从未见过,所以我检查了可能的原因。当程序变慢时,程序使用的内存没有改变。当我运行程序时,RAM 和 CPU 状态都很好。

幸运的是,以前版本的程序没有这样的问题。所以我终于找到了使程序变慢的单个语句。当我使用这个语句时,程序并没有变慢:

dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi;

但是,当我将上面的语句替换为:

dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi - lambda*w[k][i][j];

为了解决这个问题,我尽力查找并排除了原因,但我失败了……下面是简单的代码结构。对于这不是与本地语句相关的问题的情况,我将我的代码上传到谷歌驱动器。 URL 位于此问题的末尾。

MLP.h


    class MLP
    {
    private:
    ...
    double lambda;
    double ***w;
    double ***dw;
    neuron **hidden;
    ...    

MLP.cpp


    ...
    for(k = n_depth - 1; k > 0; k--)
    {
        if(k == n_depth - 1)
            ...
        else
        {
            ...
            for(j = 1; n_neuron > j; j++)
            {
                for(i = 0; n_neuron > i; i++)
                {
                    //dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi;
                    dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi - lambda*w[k][i][j];
                }
            }
        }
    }
    ...

完整源代码:https://drive.google.com/open?id=1A8Uw0hNDADp3-3VWAgO4eTtj4sVk_LZh

最佳答案

我不确定为什么它变得越来越慢,但我确实知道您可以从哪里获得一些性能。

Two and higher dimensional arrays are still stored in one dimensional memory. This means (for C/C++ arrays) array[i][j] and array[i][j+1] are adjacent to each other, whereas array[i][j] and array[i+1][j] may be arbitrarily far apart.

Accessing data in a more-or-less sequential fashion, as stored in physical memory, can dramatically speed up your code (sometimes by an order of magnitude, or more)!

When modern CPUs load data from main memory into processor cache, they fetch more than a single value. Instead they fetch a block of memory containing the requested data and adjacent data (a cache line ). This means after array[i][j] is in the CPU cache, array[i][j+1] has a good chance of already being in cache, whereas array[i+1][j] is likely to still be in main memory.

来源:https://people.cs.clemson.edu/~dhouse/courses/405/papers/optimize.pdf

使用您当前的代码,w[k][i][j] 将被读取,而在下一次迭代中,w[k][i+1][j] 将被读取。您应该反转 i 和 j,以便按顺序读取 w:

for(j = 1; n_neuron > j; ++j)
{
    for(i = 0; n_neuron > i; ++i)
    {
        dw[k][j][i] = hidden[k-1][j].y * hidden[k][i].phi - lambda*w[k][j][i];
    }
}

还要注意 ++x 应该比 x++ 稍微快一些,因为 x++ 必须创建一个包含 旧值的临时值code>x 作为表达式结果。编译器可能会在未使用该值时对其进行优化,但不要指望它。

关于c++ - 随着计算的进行,我的 C++ 程序变慢了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51422254/

相关文章:

c++ - 关于 shared_from_this 的问题

c++ - 编译 Sqlite C++ 库时 Visual Studio 2013 崩溃

c++ - 如何使用getter函数将列表推回列表?

c++ - OpenGL GLFW 窗口一打开就关闭

c++ - ADTF 过滤器触发器的默认值

tensorflow - 损失函数减小,但训练集的精度在 tensorflow 中没有变化

machine-learning - ResNet架构中如何计算梯度?

machine-learning - 为什么神经网络的权重应该初始化为随机数?

machine-learning - 反转 dropout 如何补偿 dropout 的影响并保持期望值不变?

neural-network - 神经网络中的成本函数是什么?