我遇到了一些我的程序的奇怪行为。我有一个在执行过程中被调用很多的函数,当我在这个函数中再声明一个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()
放入一个单独的文件中,汇编代码仍然很长。
答案 0 :(得分:4)
您的错误在于您没有进行优化编译,或者您的编译器已过时。未使用的变量将被任何体面的编译器完全从可执行文件中删除。
我们可以根据额外的变量,更多的缓存未命中等推测内存中possibleWays
和BadWays
的对齐,但重点是任何没有优化的分析都没有任何含义。
答案 1 :(得分:3)
在两种情况下查看中间汇编程序代码可能很有用。再添加一个变量可能会改变编译器利用CPU寄存器与堆栈分配变量的方式。前者显然更快。
答案 2 :(得分:0)
我发现了一个愚蠢的错误,导致代码速度变慢。我正在使用该对象名作为参数来实例化类的对象,如此
MyClass obj( obj );
我不知道为什么会这样,但这就是为什么我的程序很慢的原因。我想新的变量分配会导致内存发生一些变化,导致随机减速和加速。