我有一个奇怪的问题。我有以下代码:

template<clss index, class policy>
inline int CBase<index,policy>::func(const A& test_in, int* srcPtr ,int* dstPtr)
{
    int width = test_in.width();
    int height = test_in.height();

    double d = 0.0; //here is the problem
    for(int y = 0; y < height; y++)
    {

        //Pointer initializations

        //multiplication involving y
        //ex: int z = someBigNumber*y + someOtherBigNumber;
        for(int x = 0; x < width; x++)
        {
            //multiplication involving x
        //ex: int z = someBigNumber*x + someOtherBigNumber;
            if(soemCondition)
            {
                // floating point calculations
            }
            *dstPtr++ = array[*srcPtr++];
        }
    }
}

内部循环被执行近200,000次,整个功能需要100毫秒才能完成。 (使用aqtimer进行剖析)

我发现一个未使用的变量 double d = 0.0; 外循环外部并卸下相同的。更改之后,突然,该方法将用于相同数量的执行数500ms。 (慢5倍)。

这种行为在具有不同处理器类型的不同机器中可重现。 (Core2,双核处理器)。

我正在使用具有优化级别的VC6编译器 O2。 Follwing是使用的其他编译器选项:

 -MD -O2 -Z7 -GR -GX -G5 -X -GF -EHa

我怀疑编译器的优化并删除了编译器优化 /O2. 。在该功能变得正常之后,它将100ms作为旧代码。

谁能阐明这种奇怪的行为?

当我删除未使用的变量时,为什么编译器优化应该放慢性能?

注意:装配代码(更改之前和之后)看起来相同。

没有正确的解决方案

其他提示

如果更改之前和之后的汇编代码看起来相同,则错误将某种程度上连接到您的时间函数。

VC6是地狱。众所周知,它会在几种情况下生成不正确的代码,并且其优化器也不是那么先进。编译器已有十多年的历史了,甚至多年来都没有得到支持。

因此,答案实际上是“您正在使用越野编译器。期望越野车行为,尤其是在启用优化时。”

我不认为升级到现代编译器(或简单地测试代码)是一个选项吗?

显然,生成的组件不可能相同,或者没有性能差异。

唯一的问题是 在哪里 差异在于。使用越野编译器,这很可能是代码的某些完全无关的部分,突然被汇编而来并破裂。但是最有可能的是,为此功能生成的装配代码是 不是 同样的情况,差异是如此微妙,您没有注意到它们。

宣布 widthheight 作为const {unsigned} ints。 {未签名 由于高度和宽度永远不会为阴性,因此应该使用。}

const int width = test_in.width();
const int height = test_in.height();

这有助于编译器进行优化。以值为 const, ,它可以将它们放入代码或寄存器中,因为他们知道它们不会改变。另外,它可以缓解编译器必须猜测变量是否在变化。

我建议用未使用的版本打印出版本的汇编代码 double 没有。这将使您了解编译器的思维过程。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top