2015-09-08 11 views
7

Ich bin ein Schaltungsentwickler (kein Softwareassistent) und habe in den letzten 9 Monaten an einem numerischen Algorithmus gearbeitet. Als eine Möglichkeit, die Effektivität meiner Algorithmen zu bewerten, überwache ich die Zeit, die benötigt wird, um zu einer Lösung zu konvergieren.Wie kann sich meine Variablendeklaration auf die Ausführungszeit auswirken?

Vor etwa 6 Monaten entdeckte ich, dass die Art, wie ich meine Variablen deklariere, dramatische Auswirkungen auf die Zeit haben kann, die das Programm benötigt. Wenn Sie beispielsweise die Deklarationen einfach neu anordnen (siehe unten), können Sie die für die Ausführung des Codes benötigte Zeit verdoppeln. Das Ändern der Längen der Arrays wirkt sich in ähnlicher Weise auf das Problem aus.

int N, j, Iter; 
long double RealZero, RealErr, QuadIterErr, QuadX; 
long double TUV[3], QuadQP[102], RealQP[102]; 
bool Updated; 

int N, j, Iter; 
long double RealZero, RealErr, QuadIterErr, QuadX; 
long double QuadQP[102], RealQP[102]; 
bool Updated; 
long double TUV[3]; 

Ich nahm zunächst an, dass ich eine Art von Bug hatte, aber ich kann es nicht finden. Abgesehen von der Geschwindigkeit sehe ich keine anderen Anomalien, und ich bekomme die gleichen Ergebnisse, egal ob der Code langsam oder schnell läuft.

Ich fand einige Diskussionen über Probleme im Zusammenhang mit langen Doppelpackungen, aber ich verstand nichts davon, und sie sagten nie, wie man das Problem, das sie diskutierten, behob.

Kann mir jemand einen Einblick geben, was hier vor sich geht und wie man es beheben kann?

Ich brauche Konsistenz mehr als ich brauche die Geschwindigkeit. Ich verwende keine Geschwindigkeitsoptimierer (Standardeinstellungen für den Compiler) und verwende C++ Builder XE3. Ich benutze kein #pragma-Paket (wie jemand gefragt hat).

Basierend auf den Kommentaren habe ich die Deklarationen für langsame und schnelle Ausführung eingerichtet und die Basisadressen für alle langen Doppelvariablen verglichen. Ob langsam oder schnell enden die Adressen mit einem 0, 4, 8 oder C.

+4

Ich würde Cache-Shenanigans erraten, aber ich würde auch vermuten, dass ein optimierender Compiler die Deklarationen sowieso neu anordnen würde. Mit "Speed ​​Optimizers" meinst du, du sagst dem Compiler, er solle gar nicht optimieren? – awksp

+0

Oh, und welche Längenänderungen hast du gemacht? – awksp

+0

In Bezug auf Optimierer, ich meine, dass ich einfach die Standard-Compiler-Einstellungen verwende. Ich kann jede der Array-Längen ändern und die Geschwindigkeit beeinflussen, oder ich kann Dummy-Variablen hinzufügen, um die Geschwindigkeit zu beeinflussen. –

Antwort

0

user5108_Dan sagte:

Hinsichtlich Optimizern, ich meine, dass ich einfach bin mit den Standard-Compiler-Einstellungen. Ich kann jede der Array-Längen ändern und die Geschwindigkeit beeinflussen, oder ich kann Dummy-Variablen hinzufügen, um die Geschwindigkeit zu beeinflussen.

Dies ist wahrscheinlich Ihr Problem. Da der Produktionscode immer ist, sollten Sie Ihre Geschwindigkeitstests nicht auf nicht optimierten Code anwenden: Sie werden im Wesentlichen die Arbeit des Compilers erledigen!

1

Eine Sache, die definitiv tut Code Leistung beeinflussen ist nicht ausgerichtete Daten: die x86-Plattform nicht ausgerichtete Daten lesen kann (im Gegensatz zu einigen anderen Architekturen), aber eine Leistungseinbuße erleiden.

Was ist ein nicht ausgerichteter Zugriff? Wenn die Größe des Typs nicht an einer Adresse gespeichert wird, die ein Vielfaches dieser Größe ist. Wenn Sie also eine 32-Bit-Ganzzahl an einer ungeraden Adresse oder sogar an einer geraden Adresse speichern, die kein Vielfaches von 4 ist, muss die CPU möglicherweise zwei Speicherlesevorgänge durchführen, um beide Hälften der Daten zu erhalten. In diesem Fall ist die Größe von long double 8, also möchten Sie, dass sie an Adressen mit einem Vielfachen von 8 gespeichert werden - aber die ersten drei Variablen sind Ganzzahlen, was 12 ergibt, also im ersten Block der Definitionen Alle der langen Doppel werden in nicht ausgerichteten Speicheradressen gespeichert.

Der zweite Block der Definitionen scheint nicht zu unterschiedlich zu sein - aber die bool ist nach oben gerückt, wodurch TUV jetzt vollständig ausgerichtet ist. Wenn TUV der am meisten verwendete Speicher im Algorithmus war, dann könnte ich gut glauben, dass es einen Zeitunterschied gab!

Also, wie reparieren Sie es? Entweder soll der Compiler angewiesen werden, Variablen mit einer größeren Ausrichtung zu speichern (dies ist nicht zu tun mit dem Packen - das hat mit dem Speicher innerhalb einer Struktur zu tun), oder zumindest die größten typisierten Variablen an erster Stelle in den Deklarationen .

+0

Danke für die Antwort. Wie Sie sehen können, habe ich das vor etwa einem Jahr gefragt, also wird es eine Weile dauern, bis ich den Code (aus einem Archiv) überprüfen kann, um Ihre Antwort zu testen. –

Verwandte Themen