在函数内部再分配一个变量会大大增加执行时间

时间:2014-02-16 15:04:32

标签: c++ gcc memory-management cygwin

我遇到了一些我的程序的奇怪行为。我有一个在执行过程中被调用很多的函数,当我在这个函数中再声明一个double变量时,程序运行速度慢了10倍。这是功能代码:

    void MazeWall::goSomewhere( WallInfo &caller )
    {   
        double slowDown = 0;

        bool possibleWays[numberOfDirections];    
        bool BadWays[numberOfDirections];
        int weightsOfDirections[numberOfDirections] = {};   
        int numOfPosWays = findPosWays( caller, possibleWays );
        int numOfBadWays = findBadWays( caller, BadWays, possibleWays );
        int selectedDir;

        if ( numOfPosWays == numOfBadWays ) // if all ways are bad
        {
            selectedDir = randomChoice( BadWays, numberOfDirections, true ); // select a bad way
        }
        else
        {
            for ( int k = 0; k < numberOfDirections; k++ )
            {
                possibleWays[k] = possibleWays[k] && (!BadWays[k] ); // leave only good ways
            }
            int step = 32 / numberOfDirections;

            // check how occupied these ways are:
            for ( int l = 0; l < numberOfDirections; ++l )
            {
                CyclicInt directionOfSight( 0, 31, 28 );

                if ( possibleWays[l] )
                {
                    directionOfSight = directionOfSight + l*step;
                    int integralDistance = 0;
                    for ( int m = 0; m <= 8; ++m )
                    {
                        integralDistance += caller.distanceToAWall32( directionOfSight, 32 );
                        directionOfSight = directionOfSight + 1;
                    }
                    weightsOfDirections[l] = integralDistance;

                }
            }
            selectedDir = weightedRandom( weightsOfDirections, numberOfDirections );
        }
        CyclicInt cyclicDir( 0, numberOfDirections - 1, selectedDir );

        caller.step( cyclicDir ); // make 1 step in selected direction
    }

在此代码中,有一个名为slowDown的变量会导致问题。如果我发表评论,该程序运行速度很快。如果我没有将它初始化为特定值,程序也会快速运行。但是,如果我像这样离开代码,它的运行速度会快10倍。我不在程序的任何地方使用这个变量。

此外,我发现一旦我添加了一个double变量,添加另一个doubles不会影响性能,但添加第36个导致另一个速度下降,所以它不能仅仅是因为分配开销。

我总是使用相同的输入条件来测试我的程序。我使用了一个全局变量来找出调用此函数的次数 - 对于特定的测试条件大约3000次。

我尝试使用其他功能,例如findPosWays()findBadWays(),它适用于某些功能,而不适用于其他功能。

我在Windows 7上使用cygwin g ++编译器。

我的问题是,为什么会发生这种情况,我该如何避免这种行为。我想有一些内存块,其中函数应该适合,如果它们不适合,它会导致一些非常昂贵的操作,找到一个更大的块。但如果是这样,不应该在编译期间完成,而不是在运行时吗?

我担心我的代码中可能会有更多的函数具有“错误”的大小并且可能会使程序变慢,所以检测这些函数似乎很重要。

更新: 我被要求为程序的快速和慢速版本粘贴汇编代码,所以这里是: http://pastebin.com/At0Sy0ZT - 慢版

http://pastebin.com/qdY8G7C5 - 快速版

不知道这是否会有任何帮助,即使我将goSomewhere()放入一个单独的文件中,汇编代码仍然很长。

3 个答案:

答案 0 :(得分:4)

您的错误在于您没有进行优化编译,或者您的编译器已过时。未使用的变量将被任何体面的编译器完全从可执行文件中删除。

我们可以根据额外的变量,更多的缓存未命中等推测内存中possibleWaysBadWays的对齐,但重点是任何没有优化的分析都没有任何含义。

答案 1 :(得分:3)

在两种情况下查看中间汇编程序代码可能很有用。再添加一个变量可能会改变编译器利用CPU寄存器与堆栈分配变量的方式。前者显然更快。

答案 2 :(得分:0)

我发现了一个愚蠢的错误,导致代码速度变慢。我正在使用该对象名作为参数来实例化类的对象,如此

MyClass obj( obj );

我不知道为什么会这样,但这就是为什么我的程序很慢的原因。我想新的变量分配会导致内存发生一​​些变化,导致随机减速和加速。