Optimiert der Compiler sizeof ?

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Optimiert der Compiler sizeof ?

Beitrag von Neo.uc »

CHallo,

wie immer erstmal ein Stückchen Code:

Code: Alles auswählen

typedef struct _NET_CONNECTION
{
	SOCKET	Socket;	
	UINT	nID;	
	char	cIP[20];		
	char	cMAC[20];	
	char	cHostname[32];	
} NET_CONN;


<Funktion>
{
NET_CONN A;
NET_CONN B;
memcpy(&A, &B, sizeof(NET_CONN));
}
Mein Frage hierzu:

Rechnet der Compiler sizeof(NET_CONN) aus und schreibt den Wert ins Programm oder wird dies jedes mal wärend Laufzeit erneut beim Aufruf der Funktion berechnet ?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Optimiert der Compiler sizeof ?

Beitrag von Schrompf »

sizeof() ist nach meinem Wissen ein CompileTime-Konstrukt - der Wert muss zur Kompilierzeit vollständig ermittelbar sein. Demzufolge landet im Code nur die resultierende Zahl.

Randbemerkung: ein schlichtes "A = B;" anstatt des memcpy() halte ich für kürzer, klarer und wartbarer. Und spätestens, wenn A oder B keine banalen C-Strukturen mehr sind, knallt memcpy() ganz ganz böse.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Re: Optimiert der Compiler sizeof ?

Beitrag von Neo.uc »

Danke für die Antwort.

Das mit dem memcpy hab ich nur zur verdeutlichung hinzugefügt, damit ich irgendwie das sizeof in den Code bekomme ^^
Die Strukturen sind weitaus komplexer, ich hab sie hier der einfachheit halber nur gestutzt ;)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Optimiert der Compiler sizeof ?

Beitrag von Krishty »

Der Compiler kann sogar das memcpy durch eine entsprechend lange Folge von mov-Befehlen ersetzen, wenn du Intrinsics aktiviert hast.

sizeof muss zur Kompilierzeit ausgewertet werden – beispielsweise ist dies hier möglich:

Code: Alles auswählen

template <size_t ItsSize> struct Buffer {
    char Bytes[ItsSize];
};
Buffer<sizeof(int)> SomeBuffer;
// Und sogar
Buffer<sizeof(Buffer<sizeof(int)>)> OtherBuffer;
Es geht aber noch weiter: Da sizeof die Größe fast jedes Ausdrucks ermitteln kann, ohne ihn zur Laufzeit auszuführen, kann man Dummy-Funktionen deklarieren und in sizeof benutzen, die für bestimmte Typen und für den ganzen Rest („...“) unterschiedlich große Rückgabewerte haben. Da sich dann durch einen Aufruf in einem sizeof ohne Laufzeitwirkung feststellen lässt, ob ein Typ von einem anderen erbt oder in ihn konvertierbar ist, ist das ein riesiges Hilfsmittel in der Metaprogrammierung.

Ab C++0x bekommt sizeof außerdem alignof zur Seite gestellt, mit dem sich dann neben der Größe eines Ausdrucks mit gleicher Syntax auch seine Ausrichtung im Speicher abfragen lässt.

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
INe5xIlium(Freak5)
Beiträge: 32
Registriert: 29.07.2002, 11:43

Re: Optimiert der Compiler sizeof ?

Beitrag von INe5xIlium(Freak5) »

In dem Zusammenhang würde mich interessieren, was eigentlich mit size() aus der STL passiert.

Code: Alles auswählen

for(int i=0;i<array.size(),i++)
scheint schneller zu sein als

Code: Alles auswählen

int arraysize=array.size();
for(int i=0;i<arraysize,i++)
Edit: :-( alle meine Beiträge der letzten 8 Jahre sind scheinbar nicht mehr in der Statistik :cry:
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Optimiert der Compiler sizeof ?

Beitrag von Krishty »

Wie hast du das denn gebenchmarkt? Eigentlich sollte es keinen Unterschied machen und falls doch, sollte er umgekehrt ausfallen … (Btw: Am schnellsten sollte noch for(auto it = array.begin(); it < array.end(); ++it) sein.)
… aber um auf die ursprüngliche Frage zu antworten: So lange, wie der Container keine feste Größe hat, wird höchstens geinlinet. Falls er eine feste Größe hat, hängt es vom Compiler und der Implementierung der STL ab, ob noch mehr geschieht.

Vergiss die Beiträge; wir bei ZFX haben auch erst vor etwas über einem Jahr wieder bei 0 angefangen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
INe5xIlium(Freak5)
Beiträge: 32
Registriert: 29.07.2002, 11:43

Re: Optimiert der Compiler sizeof ?

Beitrag von INe5xIlium(Freak5) »

Ich muss zugeben, ich hab nur etwas wie GetSystemTickCount oder so verwendet (irgend so eine WinApi Funktion) und die Schrleife mehrmals hintereinander mit ein paar millionen durchläufen durchlaufen lassen, mir hat jemand gesagt, dass die Variable aus dem Speicher geladen wird, aber die STL so optimiert ist, dass diese funktionsaurufe als Const markiert werden können und dann im Register liegen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Optimiert der Compiler sizeof ?

Beitrag von Krishty »

Solche Minimal-Optimierungen hängen sehr stark vom Benchmark-Setup (inklusive dem Schleifenrumpf) und von den Compiler-Einstellungen ab … für eine präzise Antwort müsste man da viel Energie reinstecken. Wie gesagt, die schnellste Lösung (und dazu noch die sicherste und komfortabelste) müsste die mit dem Iterator sein.

Was die STL-Optimierung angeht – ja, die Funktion ist const deklariert, so dass der Compiler einen Hinweis hat, dass sich der Wert nicht ändert. Der Knackpunkt ist, dass das nur sagt, dass sich der Wert durch die Funktion nicht ändert – falls der Container durch eine andere Funktion, z.B. im Schleifenrumpf, verändert wird (und das ist ja durchaus gängige Praxis), ist der Compiler deshalb trotzdem gezwungen, bei jedem Durchlauf aufs Neue den Wert zu laden. Selbst, wenn der Vektor komplett const ist, könnte Aliasing (dass der Vektor noch durch einen Zeiger oder eine Referenz von dort aus verändert werden könnte, wo man es nicht vermutet) den Compiler zwingen, jedes Mal neu zu laden. Falls der Schleifenrumpf komplexer ist als ein paar Basis-Operationen, wird der Wert eh aus den Registern verdrängt, bevor der nächste Vergleich ansteht (und muss deshalb sowieso neu geladen werden). Zu guter Letzt ist die STL noch implementation-defined, d.h. sie könnte, statt den Wert aus dem Speicher zu laden, Drucker und Scanner anschmeißen und ihn bei jeder Veränderung auf ein Blatt Papier drucken und das bei jeder Abfrage neu einscannen. So dämlich das auch wäre – es wäre standardkonform und zeigt, dass man keine pauschalen Urteile über die Optimierungsfähigkeit von STL-Funktionen fällen kann.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
klickverbot
Establishment
Beiträge: 191
Registriert: 01.03.2009, 19:22
Echter Name: David N.

Re: Optimiert der Compiler sizeof ?

Beitrag von klickverbot »

Krishty hat geschrieben:Zu guter Letzt ist die STL noch implementation-defined, d.h. sie könnte, statt den Wert aus dem Speicher zu laden, Drucker und Scanner anschmeißen und ihn bei jeder Veränderung auf ein Blatt Papier drucken und das bei jeder Abfrage neu einscannen.
Ich habe zwar zum eigentlichen Thema kaum etwas zu sagen (den vom Compiler generierten Assembler-Code anzuschauen sollte etwaige Fragen schnell beseitigen), aber ich muss Krishty mal ein Lob aussprechen: Der Vergleich ist eben so kreativ wie einfallsreich, du solltest unbedingt noch ein paar Tutorials schreiben. ;)
Antworten