es ist einfach erstaunlich wieviel halbwissen und unwissen hier verbreitet wird.
1. es ist FALSCH, dass jede variable (zahl) im speicher eine komplette 8 byte (bei 64bit) oder 4 byte (bei 32bit) belegt.
2. es ist FALSCH, dass sich die breite der datentypen beim wechsel auf 64Bit verdoppelt.
3. es ist FALSCH, dass ein int genau so groß ist wie der "addressbereich".
4. es ist FALSCH, dass man nur mit 64Bit mehr als 4GiB arbeitsspeicher addressieren kann.
zu 1. der compiler versucht den speicher so an zu ordnen, dass auf diesen effiziennt zugegriffen wird (so weit es ihm erleubt und möglich ist). dies bedeutet er versucht so genannte "unaligned" zugriffe zu vermeiden. wenn in C eine struct folgender art erzeugt wird. wird der compiler warscheinlich lücken einbauen, welche somit verlorenen platz darstellen. struct foo { int32_t a; int16_t b; int32_t c; int32_t d; int64_t e; }; auf einem 32Bit system wir ein compiler ziemlich sicher nach den attribut 'b' 16Bit leer lassen um unaligned zugriffe auf den nachfolgenden 32Bit wert ('c') zu vermeiden.
auf einem 64Bit system wird nach dem attribut 'a' warscheinlich keine lücke erzeugt sondern direkt der 16bit wert ('b') folgen, da dieser keine 64bit "grenze" überschneidet. nach 'b' wird aber vermutlich wie auch einem 32Bit system eine lücke erzeugt werden. zwischen den attribute 'c', 'd' und 'e' wird vermutlich ebenfalls keine lücke erzeugt werden.
das laden von Werten ungleich der addressbreite ist nicht ganz so effizient wie das laden eine variable, die genau der addressbreite entspricht. somit kann es sinnvoll sein einen datentyp zu wählen der viel größer ist als die eigentliche addressbreite, wenn dieser heufig aus dem speicher geladen werden muss. dies ist aber schwer zu ermitteln und bedarf viel erfahrung und/oder gutem profiling.
zu 2. unter linux hat sich die breite nur weniger datentypen beim wechsel auf 64Bit verändert. die bekanntesten sind: long: 32bit: 4byte; 64bit: 8byte double: 32bit: 12byte; 64bit: 16byte ein pointer; 32bit: 4byte; 64bit: 8byte (alle diese zahlen beziehen sich auf übliche linux systeme 32bit/x86 bzw 64/x86_64)
zu 3. der datentyp int ist unter linux auf 32bit/x86 und 64/x86_64 jeweilst 32bit/4byte.
alle angaben beziehen sich auf die Programmiersprache C (c99) unter linux auf x86 oder x86_64 systemen.
zu 4. PAE (Physical Address Extension) erlaubt es einem betriebsystem auch ohne 64Bit unterstützung und ohne 64Bit prozessor mehr als 4GiB arbeitsspeicher zu addressieren. https://secure.wikimedia.org/wikipedia/en/wiki/Physical_Address_Extension http://kerneltrap.org/node/2450
Das kannst du so handhaben wie es es dir lieb ist. Wenn du willst kannst du sogar die Lücken vermeiden oder ein 128Bit Alignment anstreben um SSE2 nutzen zu können (ich glaube ab /O2 wird es immer gemacht, bin mir aber nicht sicher). Es gibt praktisch 2 Fälle. Entweder es ist unkritisch so dass man sich überhaupt nicht dafür interessiert oder es ist kritisch und dann packt man es selber wie man es möchte.
Verstehe daher dein Eschaufieren hier nicht so wirklich.. man sollte nicht aus jeder Fliege einen Elefanten züchten.
ok, ich glaube du hast sehr viele worte aus meinem Post überlesen. ich habe von »warscheinlichkeiten« gesprochen. es ist mir bekannt, dass ich z.B. über zu hilfe nahme compilerspeziefischer "flags" packed struckts erzeien kann. ebenso kann ich die anordnung der daten in meiner struct so wählen, dass keine lücken entstehen.
und ja ich kann auch über compiler speziefische "flags" eine, wie von dir schon angesprochen, 128Bit alignmant erzwingen.
Ich habe lediglich die fehlannahme, dass jede variable im speicher _immer_ komplette 32/64 belegen würde wiederlegt und dies als beweis genutzt. ich habe nirgens ausgeschloßen, dass es noch weitere möglichkeiten gibt wie das alignment aussehen kann.
und nun zum thema, dass ich mich nicht "Eschaufieren" soll. ich war der meinung, dass die kommentar funktion für diskusionen gedacht ist. und ich vermute, dass leser, welche weniger wissen um die interna der C programmierung haben doch froh sind, wenn einige der behauptungen welche im zusammenhang mit 32/64Bit Betriebsystemene gemacht wurden klar gestellt werden.
es ist einfach erstaunlich wieviel halbwissen und unwissen hier verbreitet wird.
1. es ist FALSCH, dass jede variable (zahl) im speicher eine komplette 8 byte (bei 64bit) oder 4 byte (bei 32bit) belegt.
2. es ist FALSCH, dass sich die breite der datentypen beim wechsel auf 64Bit verdoppelt.
3. es ist FALSCH, dass ein int genau so groß ist wie der "addressbereich".
4. es ist FALSCH, dass man nur mit 64Bit mehr als 4GiB arbeitsspeicher addressieren kann.
zu 1.
der compiler versucht den speicher so an zu ordnen, dass auf diesen effiziennt zugegriffen wird (so weit es ihm erleubt und möglich ist). dies bedeutet er versucht so genannte "unaligned" zugriffe zu vermeiden. wenn in C eine struct folgender art erzeugt wird. wird der compiler warscheinlich lücken einbauen, welche somit verlorenen platz darstellen.
struct foo {
int32_t a;
int16_t b;
int32_t c;
int32_t d;
int64_t e;
};
auf einem 32Bit system wir ein compiler ziemlich sicher nach den attribut 'b' 16Bit leer lassen um unaligned zugriffe auf den nachfolgenden 32Bit wert ('c') zu vermeiden.
auf einem 64Bit system wird nach dem attribut 'a' warscheinlich keine lücke erzeugt sondern direkt der 16bit wert ('b') folgen, da dieser keine 64bit "grenze" überschneidet. nach 'b' wird aber vermutlich wie auch einem 32Bit system eine lücke erzeugt werden. zwischen den attribute 'c', 'd' und 'e' wird vermutlich ebenfalls keine lücke erzeugt werden.
das laden von Werten ungleich der addressbreite ist nicht ganz so effizient wie das laden eine variable, die genau der addressbreite entspricht. somit kann es sinnvoll sein einen datentyp zu wählen der viel größer ist als die eigentliche addressbreite, wenn dieser heufig aus dem speicher geladen werden muss. dies ist aber schwer zu ermitteln und bedarf viel erfahrung und/oder gutem profiling.
zu 2.
unter linux hat sich die breite nur weniger datentypen beim wechsel auf 64Bit verändert. die bekanntesten sind:
long: 32bit: 4byte; 64bit: 8byte
double: 32bit: 12byte; 64bit: 16byte
ein pointer; 32bit: 4byte; 64bit: 8byte
(alle diese zahlen beziehen sich auf übliche linux systeme 32bit/x86 bzw 64/x86_64)
zu 3.
der datentyp int ist unter linux auf 32bit/x86 und 64/x86_64 jeweilst 32bit/4byte.
alle angaben beziehen sich auf die Programmiersprache C (c99) unter linux auf x86 oder x86_64 systemen.
zu 4.
PAE (Physical Address Extension) erlaubt es einem betriebsystem auch ohne 64Bit unterstützung und ohne 64Bit prozessor mehr als 4GiB arbeitsspeicher zu addressieren.
https://secure.wikimedia.org/wikipedia/en/wiki/Physical_Address_Extension
http://kerneltrap.org/node/2450
Mit freundliche Grüßen
iluminat23
Zu 1)
Das kannst du so handhaben wie es es dir lieb ist. Wenn du willst kannst du sogar die Lücken vermeiden oder ein 128Bit Alignment anstreben um SSE2 nutzen zu können (ich glaube ab /O2 wird es immer gemacht, bin mir aber nicht sicher). Es gibt praktisch 2 Fälle. Entweder es ist unkritisch so dass man sich überhaupt nicht dafür interessiert oder es ist kritisch und dann packt man es selber wie man es möchte.
Verstehe daher dein Eschaufieren hier nicht so wirklich.. man sollte nicht aus jeder Fliege einen Elefanten züchten.
ok, ich glaube du hast sehr viele worte aus meinem Post überlesen. ich habe von »warscheinlichkeiten« gesprochen. es ist mir bekannt, dass ich z.B. über zu hilfe nahme compilerspeziefischer "flags" packed struckts erzeien kann. ebenso kann ich die anordnung der daten in meiner struct so wählen, dass keine lücken entstehen.
und ja ich kann auch über compiler speziefische "flags" eine, wie von dir schon angesprochen, 128Bit alignmant erzwingen.
Ich habe lediglich die fehlannahme, dass jede variable im speicher _immer_ komplette 32/64 belegen würde wiederlegt und dies als beweis genutzt. ich habe nirgens ausgeschloßen, dass es noch weitere möglichkeiten gibt wie das alignment aussehen kann.
und nun zum thema, dass ich mich nicht "Eschaufieren" soll. ich war der meinung, dass die kommentar funktion für diskusionen gedacht ist. und ich vermute, dass leser, welche weniger wissen um die interna der C programmierung haben doch froh sind, wenn einige der behauptungen welche im zusammenhang mit 32/64Bit Betriebsystemene gemacht wurden klar gestellt werden.
gruß
iluminat23
PAE erlaubt dem Betriebssystem mehr als 4GB zu adressieren, richtig. Aber pro Prozess sind weiterhin zur max. 4GB möglich.
das ist natürlich korrekt. dies ist auch im artikel auf kerneltrap erläutert. ich hätte es direkt schreiben sollen. danke für deine ergänzung.
gruß
iluminat23
Danke für die ausführlichen Infos zu den C99-Datentypen.