首页 > 解决方案 > 随着计算的进行,我的 C++ 程序变慢

问题描述

我用 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

标签: c++neural-network

解决方案


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

二维和更高维数组仍然存储在一维内存中。这意味着(对于 C/C++ 数组)array[i][j]array[i][j+1] 彼此相邻,而array[i][j]array[i+1][j]可能相距任意远。

以或多或少的顺序方式访问存储在物理内存中的数据,可以显着加快您的代码速度(有时提高一个数量级或更多)!

当现代 CPU 将数据从主内存加载到处理器缓存中时,它们会获取多个值。相反,它们获取包含请求数据和相邻数据的内存块(高速缓存行)。这意味着 afterarray[i][j]在 CPU 缓存中,array[i][j+1]很有可能已经在缓存中,而array[i+1][j]很可能仍然在主内存中。

资料来源: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++必须创建一个包含旧值的临时值x作为表达式结果。当该值未使用时,编译器可能会对其进行优化,但不要指望它。


推荐阅读