Verweis auf Element in for-Schleife
-
Im schlimmsten Fall wird ja in jeder i-iteration Speicher für dummy reserviert beschrieben und am Ende jeder i-teration weider freigegeben.
Definiert man es außerhalb der h-Schleife wird nur einmal reserviert und freigegeben und muss in jeder i-iteration nur beschrieben werden.
Wenn ich nun "ind" und "var" nicht definieren wird der index in jeder j-iteration immer und immer wieder berechnet, darauf verwiesen und geändert (Kompiler optimiert das aber glaub weg.)
Nun ist die Frage, ob jetzt in jeder i-ter auch für "ind" udn "var" Speicher reserviert wird, beschrieben und wieder freigegeben wird oder es z.B. nur im Register gespeichert bleibt.
Also ob dann in jeder j-iter erst var gelesen werden müsss und dann die Rechnung ausgeführt wird oder ob nur einmal gelesen wird und dann alle Rechungen ausgeführt werden.Die Beschreibung ist bestimmt nicht ganz fehlerfrei.
Der eigentlich Sinn ist, dass ich an mehreren Stellen auf das gleiche Datum verweisen möchte ohne jedes mal die die Position dessen neu zu berechnen.
-
Was soll in deiner for-Schleife
for(j=ind[i]; j < ind[h]; j++){
denn dasind[i]
sein? Du hast es doch vorher gerade mitint &ind = myIndVar[...];
gesagt, dass ind eine Referenz auf int ist und kein Array -
der gezeigte Code dürfte nicht kompilieren wegen eines Fehlers wie "error: subscripted value is not an array, pointer, or vector".Ansonsten: was möchtest du mit der Frage erreichen? Ist es deiner Meinung nach ein Problem, in der Schleife die Variable zu erstellen? Es handelt sich ja nur um eine Adresse, nicht um ein Objekt mit Konstruktor. Das ist also eine Zahl, da ist kein separater "Erstellungsprozess" nötig. Wahrscheinlich wird die Adresse eh nur in irgendeinem Register gehalten.
-
1234567 schrieb:
Im schlimmsten Fall wird ja in jeder i-iteration Speicher für dummy reserviert beschrieben und am Ende jeder i-teration weider freigegeben.
Definiert man es außerhalb der h-Schleife wird nur einmal reserviert und freigegeben und muss in jeder i-iteration nur beschrieben werden.Automatische Variablen werden nicht reserviert oder freigegeben. Wir sind hier nicht in Python. Da passiert gar nichts, deine Sorgen sind unbegründet. Die Variablen sind bloß eine Abstraktion auf Quellcodeebene. Während des eigentlichen Programmablaufs haben sie keine fassbare Substanz.
-
SeppJ schrieb:
Während des eigentlichen Programmablaufs haben sie keine fassbare Substanz.
Du bist wahrlich ein begnadeter Rhetoriker.
-
Ja das "ind" stimmt nicht ganz. Müsste eher so aussehen:
int* const ind = myIndVar[ h * i + h *const1 + i * const2 ]; //int* const &ind = myIndVar[ h * i + h *const1 + i * const2 ]; //oder so besser?
SeppJ schrieb:
Automatische Variablen werden nicht reserviert oder freigegeben. Wir sind hier nicht in Python. Da passiert gar nichts, deine Sorgen sind unbegründet. Die Variablen sind bloß eine Abstraktion auf Quellcodeebene. Während des eigentlichen Programmablaufs haben sie keine fassbare Substanz.
Ah ok, bei "int dummy" in der Schleife aber schon?
-
1234567 schrieb:
J
SeppJ schrieb:
Automatische Variablen werden nicht reserviert oder freigegeben. Wir sind hier nicht in Python. Da passiert gar nichts, deine Sorgen sind unbegründet. Die Variablen sind bloß eine Abstraktion auf Quellcodeebene. Während des eigentlichen Programmablaufs haben sie keine fassbare Substanz.
Ah ok, bei "int dummy" in der Schleife aber schon?
Warum?
-
Arcoth schrieb:
SeppJ schrieb:
Während des eigentlichen Programmablaufs haben sie keine fassbare Substanz.
Du bist wahrlich ein begnadeter Rhetoriker.
Da musste ich auch lange drüber nachdenken
1234567 schrieb:
J
SeppJ schrieb:
Automatische Variablen werden nicht reserviert oder freigegeben. Wir sind hier nicht in Python. Da passiert gar nichts, deine Sorgen sind unbegründet. Die Variablen sind bloß eine Abstraktion auf Quellcodeebene. Während des eigentlichen Programmablaufs haben sie keine fassbare Substanz.
Ah ok, bei "int dummy" in der Schleife aber schon?
Ich erkläre dir, dass und warum das nicht so ist und deine Folgerung ist, dass es so ist?
-
1234567 schrieb:
Wie macht man das nun aber mit "ind" und "var"?
Es ist für den Optimizer sogar günstiger wenn du ind und var innerhalb der Schleife definierst. Der kommt damit viel besser/leichter klar als mit einer Variable die weiter aussen Definiert wird und pro Durchlauf neu zugewiesen.
Und ich würde gleich
ind[
i]
undind[h]
als Variable rausziehen statt nurind
. Schliesslich isth
für die innere schleife auch eine Invariante, und der Wert der inind[h]
abgespeichert ist darf sich auch nicht ändern.
(Beiind[
i]
wäre es egal, aber beiind[h]
ist es günstig wenn das nicht bei jedem Durchlauf neu geladen werden muss. Und der Compiler könnte u.U. übersehen dass sich weder h nochind[h]
ändern können.)
-
hustbaer schrieb:
1234567 schrieb:
Wie macht man das nun aber mit "ind" und "var"?
Es ist für den Optimizer sogar günstiger wenn du ind und var innerhalb der Schleife definierst. Der kommt damit viel besser/leichter klar als mit einer Variable die weiter aussen Definiert wird und pro Durchlauf neu zugewiesen.
Und ich würde gleich
ind
undind[h]
als Variable rausziehen statt nurind
. Schliesslich isth
für die innere schleife auch eine Invariante, und der Wert der inind[h]
abgespeichert ist darf sich auch nicht ändern.
(Beiind[i]
wäre es egal, aber beiind[h]
ist es günstig wenn das nicht bei jedem Durchlauf neu geladen werden muss. Und der Compiler [i]könnte u.U. übersehen dass sich weder h noch ind[h] ändern können.)Ja im eigentlichen code is ind[i] und ind[h] schon vorher definiert.
Das es mit der dummy variable nicht so ist, dachte ich weil ich mich glaube daran zu erinnern, dass ein ander mal das ziemlich auf die Laufzeit geschlagen ist ( könnte auch java gewesen sein). Ich habe es aber noch einmal getestet, macht scheinbar wirklich keinen Unterschied, Selbst die Definition eines 1000er arrays in der Schleife hat nix bewirkt.
-
Noch einmal: Was stellst du dir unter dem "Erstellen" einer Variable vor?
Es gibt im eigentlichen Programmablauf keine Variablen. Variablen sind etwas für den Programmierer. Es mag Orte geben, an denen ein Programm Werte ablegt, aber diese Orte müssen nicht erstellt werden. Die existieren einfach, ganz egal ob etwas mit ihnen gemacht wird oder nicht.
Bei Sprachen wie Basic oder Python mag das anders sein, aber die funktionieren ganz anders als eine compilierte Sprache. Es würde mich auch schwer wundern, wenn du bei Java tatsächlich einen Effekt gemessen haben solltest, außer vielleicht es handelt sich um irgendeine komplexe Klasse.
-
Schau dir doch mal den generierten ASM-Output für verschiedene Varianten an...
Für-O2
oder
-O3
sollte das schon erfolgreich in irgendein register wegoptimiert werden, ganz gleich, wo die Variable definiert wird...
-
Ich möchte nun verhindern, dass in der inneresten Schleifen immer die indizes berechnet werden und habe "ind" und "var" ausgelagert.
Im schlimmsten Fall wird ja in jeder i-iteration Speicher für dummy reserviert beschrieben und am Ende jeder i-teration weider freigegeben.
1. ind/var werden auf dem Stack liegen da wird gar nichts angelegt oder freigegeben
2. du hast definitiv keine Ahnung wie der Optimierer arbeitet
3. wie kommst du überhaupt darauf das irgendeine deiner gezeigten Zeilen Geschwindigkeitsrelevant ist?mit dem geringen Basis-Wissen was "optimieren" zu wollen ist totaler quatsch, du machst dir arbeit wo absolut nichts zu holen ist
ohne Profiler oder Benchmarks macht man sowas eh keinen Sinn, und darauf Achten immer nur mit eingeschalteter Optimierung (Release) testen sonst schaust dir super-langsame Debug-Builds an deren Geschwindigkeits-Aussage = 0 ist
-
NablaSquaredG schrieb:
sollte das schon erfolgreich in irgendein register wegoptimiert werden, ganz gleich, wo die Variable definiert wird...
Ob Register oder nicht, spielt keine Rolle! Es kostet keine Zeit, eine Variable zu "erstellen", denn es gibt kein Erstellen! Selbst wenn das ganz ohne jede Optimierung übersetzt wird, so dass der Bezeichner 1:1 einer bestimmten Speicheradresse zugeordnet werden kann: Die Speicheradresse existiert sowieso! Die muss nicht erstellt, reserviert oder vorbereitet werden.
Stell dir vor, du hast ein Regal. Spielt es eine Rolle, wann du den Entschluss fasst, etwas an einem bestimmten Ort da drin abzustellen? Es mag Zeit brauchen, etwas an den Ort zu stellen und wieder heraus zu nehmen, aber Abstellen und herausnehmen möchtest du ja sowieso. Wie lange das Hineinlegen und Herausnehmen dauert ist aber vollkommen unabhängig davon, ob du den Entschluss dazu spontan fasst, wenn du etwas konkretes zum Ablegen hast (in der for-Schleife); oder den Platz im Voraus für etwas frei hältst, von dem du weißt, dass du es später ablegen musst (vor der for-Schleife).
Der wirkliche Unterschied ist, dass bei letzterem der Platz eventuell ungenutzt frei bleibt, weil nichts dort liegt, aber der Platz noch freigehalten wird. Wenn das Regal nicht viele Plätze hat, kann das relevant sein. Das ist es, was hustbaer meinte (siehe sein Beitrag). Bei solchen Mini-Funktionen mag der Optimierer auch von alleine erkennen können, wann genau etwas wo gebraucht wird und wann nicht, und er kann und wird sich dann einfach nicht an die Lebenszeit deiner Deklarationen halten (wie schon so oft gesagt: Variablen, Scopes, usw. sind alles Hilfsmittel für den Programmierer, es gibt sie nicht mehr im eigentlichen Programm). Wenn es wirklich kompliziert wird, kann das aber auch nicht gelingen, und man verhindert durch zu breit gefasste Gültigkeitsbereiche, dass der Optimierer optimal arbeiten kann. Am schlimmsten ist dies, wenn man Variablen global macht, weil der Optimierer sich dann nicht mehr darauf verlassen kann, dass diese Variable nicht von anderswo im Programm aus geändert wird.