Frage

Ich habe ein seltsames Problem. Ich habe folgenden Code:

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++];
        }
    }
}

Die innere Schleife wird fast 200.000-mal und die gesamte Funktion übernimmt für die Fertigstellung von 100 ms ausgeführt. (Profil mit AQTimer)

fand ich eine nicht verwendete Variable double d = 0.0; außerhalb der äußeren Schleife und entfernt das gleiche. Nach dieser Änderung ist, plötzlich das Verfahren 500ms für die gleiche Anzahl von Hinrichtungen nehmen. (5-mal langsamer).

Dieses Verhalten ist reproduzierbar in verschiedenen Maschinen mit unterschiedlichen Prozessortypen. (Core2, Dual-Core-Prozessoren).

Ich bin mit VC6 Compiler mit Optimierungsstufe O2. Follwing werden die anderen Compiler-Optionen verwendet:

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

I Compiler-Optimierungen vermutet und die Compiler-Optimierung /O2 entfernt. Danach Funktion wurde normal und es ist 100ms als alter Code nehmen.

Kann jemand etwas Licht auf dieses seltsame Verhalten werfen?

Warum Compiler-Optimierung sollte die Leistung verlangsamen, wenn ich nicht verwendetes Variable entfernen?

Hinweis: Der Assembler-Code (vor und nach der Änderung) sah gleichen

.

Keine korrekte Lösung

Andere Tipps

Wenn der Assembler-Code sieht gleich vor und nach der Änderung der Fehler irgendwie verbunden ist, wie Sie die Funktion Zeit.

ist VC6 Buggy wie die Hölle. Es ist bekannt, einen falschen Code in mehreren Fällen zu erzeugen, und seine Optimierer ist nicht alles, was entweder vorgeschoben. Der Compiler ist mehr als ein Jahrzehnt alt, und noch nicht einmal seit vielen Jahren unterstützt.

Also wirklich, die Antwort „Sie einen Buggy-Compiler verwenden. Buggy Verhalten erwarten, vor allem, wenn Optimierungen aktiviert sind.“

Ich nehme nicht an, ein Upgrade auf einen modernen Compiler (oder einfach testen Sie den Code auf eins) ist eine Option?

Offensichtlich kann die generierte Assembly nicht gleich sein, oder es gäbe keinen Unterschied in der Leistung sein.

Die Frage ist nur mit der Unterschied liegt. Und mit einem Buggy-Compiler, kann es durchaus einig völlig unabhängig Teil des Codes sein, die anders und Pausen werden plötzlich zusammengestellt. Wahrscheinlich aber, der Assembler-Code für diese Funktion erzeugt wird, ist nicht die gleiche, und die Unterschiede sind nur so subtil man sie nicht bemerken.

Declare width und height als const {unsigned} ints. { Die unsigned sollte, da Höhen eingesetzt werden und Breiten sind nie negativ. }

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

Dies hilft, den Compiler mit der Optimierung. Mit den Werten wie const, kann er sie im Code platzieren oder in den Registern, wohl wissend, dass sie sich nicht ändern werden. Außerdem ist es entlastet die Compiler zu müssen erraten, ob die Variablen verändern oder nicht.

Ich schlage vor, das Drucken des Assembler-Code der Versionen mit dem ungenutzten double und ohne. Dies gibt Ihnen einen Einblick in den Denkprozess des Compilers.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top