PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wann sind Variablenzuweisungen schneller als eine Multiplikation/Division?



Catonga
12-04-2003, 02:58
Hallo,

ich habe folgende Frage,
wann lohnt es sich das Ergebnis einer Multiplikation/Division
in eine Variable zu speichern anstatt das Ergebnis neu zu Berechnen?
Bzw. unter welchen Umständen ist eine Neuberechnung schneller
als eine Wertzuweisung zu einer Variablen und deren Folgen wie Zugriff auf den Inhalt
der Variable (vermutlich auch noch wenn dieser erst umständlich aus dem Hauptspeicher zu holen ist anstatt aus einem Register) .


Um das kurz zu verdeutlichen habe ich hier folgenden Algorithmus (C++ Code),
er berechnet die Verbleibenden Tage nach Abzug der Jahre und
berücksichtig dabei ganz grob die Schaltjahre:




ergebnis = (tage - ( (( (tage/365) / 4)*366) + ( ((tage/365) - ( (tage/365) /4)) *365) ))


Die Variable "tage" enthält sämtliche vergangenen Tage zwischen einem bestimmten Zeitraum (der auch über mehrere Jahre hinweg gehen kann).
Z.b. tage = 3000;
(mit einer For Schleife wäre das ganze vermutlich wegen den Schaltjahren genauer, aber das soll jetzt hier erstmal nur als Beispiel dienen)




Wie man sieht wird hier im selben Algorithmus mehrmals berechnet wieviele Jahre
in den Wert von "tage" hineinpassen, daher stellt sich die Frage ob man diese Berechnung nicht einfach nur einmal durchführt und dann einer Variable zuweißt um
dann mit dieser weiterzurechnen.
Z.b. so:



jahre= tage/365;
ergebnis = (tage - ( (( jahre/4)*366) + (( jahre - (jahre/4)) * 365) ));

Hier würde man sich also 2 weitere Divisionen sparen,
da das Ergebnis in "jahre" enthalten ist.


Das könnte man dann noch weiterverfeindern und die Berechnung der Anzahl der Schaltjahre ebenfalls nochmal in eine Variable speichern:



jahre= tage/365;
schaltjahre = jahre/4;
ergebnis = (tage - ( (schaltjahre*366) + ((jahre - schaltjahre)*365) ) ):


Hier hätte man dann 2+1, also 3 Divisionen gespart.



Was ist also schneller, 3 Divisionen extra zu berechnen oder das Speichern der Werte in Variablen und den damit eventuell resultierenden Zugriff auf den Hauptspeicher,
das anlegen von Platz für die Variable im Speicher sowie das umkopieren des Wertes vom Hauptspeicher zu einem Register etc.?

peschmae
12-04-2003, 07:34
solche sachen hab ich mich auch schon gefragt.

Am einfachsten machst du wohl ne for - schleife von 1 - 1000000, schaltest alle Optimierungen aus und lässt das ganze mit "time" siebenmal laufen

Ein Jahr würde ich übrigens zu 365,24 Tage nehmen, statt deiner komischen (???) Schaltjahrrechnung...
das ist genauer und wohl auch schneller (oder rechnest du nur mit int's?)

MfG Peschmä

anda_skoa
12-04-2003, 12:43
Eine Division ist aufjeden Fall langsamer als ein Speicherzugriff.

Vorallem, weil du die Division wirklich jedesmal machen musst, der Compiler den Speicherzugriff aber durch geschickte Registerausnutzung vermeiden kann.

Bei einer Multiplikation hängts von der Hardware ab. DSPs können meist Multiplikationen in einem Zyklus berechnen (Hardwaremultiplizierer)

Ciao,
_

Catonga
12-04-2003, 14:17
Original geschrieben von peschmae

Ein Jahr würde ich übrigens zu 365,24 Tage nehmen, statt deiner komischen (???) Schaltjahrrechnung...
das ist genauer und wohl auch schneller (oder rechnest du nur mit int's?)

MfG Peschmä

In diesem Beispiel sind es nur long ints,
daher die Ganzzahlen.




Original geschrieben von anda_skoa

Eine Division ist aufjeden Fall langsamer als ein Speicherzugriff.

Vorallem, weil du die Division wirklich jedesmal machen musst, der Compiler den Speicherzugriff aber durch geschickte Registerausnutzung vermeiden kann.


Ok, dann ist die Variablenzuweisung anstatt der Neuberechnung wohl die schnellere Variante, danke.

Jinto
12-04-2003, 15:35
Was schneller ist, lässt sich nicht auf generell beatnworten. Eine Division muss nicht zwangslüfig langsamer sein, als ein Speicherzugriff (wenn am Cache vrobei, dann wirds vermutlich noch komplizierter). Es gibt auch noch so tolle Dinge wie: Register Neuordnung, Parallelisierung, etc.

Letztendlich hängt es vom Compiler ab und welchen Code er daraus produziert. Wenn der Compiler hingeht und deine Variable in den Speicher schreibt, er aber im gegenzug deine Berechnung direkt auf die vorhandenen Register umschreibt, dann ist deine Variablenmethode wesentlich langsamer.

Letztendlich wirst du die Frage aber nur beantworten können, wenn du dir den produzierten Assemblercode ansiehst. Dies wird deine Frage aber nur für genau dieses Beispiel und genau diesen verwendeten Compiler mit den verwendeten Optimierungen zutreffen, sobald sich auch nur eines davon ändert, kann das Ergebnis ganz anders aussehen.

HTH