![]() |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Zitat:
@christian_r: Der Compiler führt ein Alignment durch bei der Generierung deines Codes, damit der Prozessor dort nicht extra arbeiten muss. Wenn du eine Variable als Byte definierst, dann hält er 32 Bit vor (32 Bit Compiler), nutzt aber nur ein Byte davon. Dadurch kann der Prozessor immer 32 Bit beim Lesezugriff holen bzw. Schreiben. Der vom Compiler generierte Code wiederrum achtet aber darauf, nur die von dir definierten 8 Bit zu nutzen. Hintergrund: Wenn der Compiler einen echten 8 Byte nehmen sollte und du diesen liest, liest die CPU trotzdem immer einen Wert, der so gross ist wie sein Datenbus ist, ein. Dies ist die kleinste Einheit, die er bei einer Anfrage an den RAM stellen kann, da dieser auch einen solch breiten Datenbus hat. Er hat also beim Lesezugriff auf die adressierte RAM Stelle immer den gesamten Datenbus mit den Daten belegt. Wenn nun der Prozessor nur 8 Bit haben will (1 Byte), dann gehen über den Datenbus trotzdem 32 Bit rüber, gehen durch den Cache, etc. und die CPU schmeisst nachher 24 Bit von den eingelesenen Werten weg, da es nur 8 Bit braucht. Dies ist ein extra Aufwand von der CPU. Wenn alle Datentypen versuchen eine durch die Breite des Datenbusses teilbare Grösse zu haben, dann kann der Prozessor optimal arbeiten. Wenn du z.B. einen Record mit einen Word und einen Integer nacheinander definierst, dann werden beide an einer durch 4 teilbaren Adresse angelegt. Der Record wird 16 Byte gross sein, was optimal für die CPU ist, aber nachteilig, wenn du z.b. eine Datei einlesen willst, der diese Struktur enthält, weil dort das Word nur 16 Bit gross sein soll. Dafür kannst du dann das "packed" Schlüsselwort verwenden. Damit schaltest du das Aligment ab und alle Werte liegen in ihrer definierten Grösse nacheinander im Speicher. Damit kommt es aber auch dazu, dass der Integer auf einer nur durch 2 teilbaren Adresse liegt. Da der Datenbus aber 32 Bit gross ist, muss die CPU, um diesen Integerwert zu lesen, zweimal lesen. Einmal adressiert er die Adresse mit den oberen 16 Bit des integers und liest diese ein. Am Datenbus liegen dann oben 16 Bit das Word an und in den unteren 16 Bit die oberen 16 Bit des Integers an. Diese holt sich die CPU raus und merkt sich diese um danach die darauffolgende Adresse (4 Bytes weiter) zu lesen. In diesen findet er in den oberen 16 Bit (der 32 Bits die am Datenbus anliegen) die für den Integer unteren 16 Bits. Diese setzt er zusammen und erhält nun endlich deinen Integer den du wolltest. Aber er musste zweimal lesen um diesen zu erhalten. Grundlegend sollte das Problem nun verständlich sein. Es ist immer zu versuchen die Daten an aligned Adressen abzulegen und das versucht der Compiler von Haus aus. Ungerade Adressen sind ein graus für die CPU, weil er zweimalig lesen muss. Heutzutage sorgen Sprungvorhersage, Adressvorhersage und Cache pre filling dafür, dass nebenbei die CPU ermittelt, wo der Code ein paar Opcodes später hinspringt, was er als nächstes adressiert bzw. lesen will, um diese Aktionen schon vorher zu erledigen. Da wird dann mal schon ein paar Opcodes zuvor eine Adresse vom Hauptspeicher ausgelesen, die erst später vom Code adressiert wird. Auch wird vorhergesagt, wohin bestimmte Verzweigungen gehen, um im Idealfall den Code schon in den Cache geladen zu haben, etc. Im besten Falle fallen WaitStates weg (Wartezyklen die die CPU einlegt zwischen Adressierung und Freigabe des Datenbusses) und der Cache hält fast alle Daten vor und im schlimmsten Falle war die Vorhersage falsch und alle Daten müssen besorgt werden und der gesamte Cache enthält falsche Daten und muss geleert werden. All diese Bemühungen der CPU und dieser kleiner Helferleins kann man sich gut in CPU internen Register (MSR) anschauen und auch deren Effizienz ermitteln. Mit diesen Registern und ein paar Anleitungen vom CPU Hersteller, können die Compiler optimierten Code bauen, die auch einwandfrei von diesen Helferleien unterstützt wird und deren falschen Voraussagen auf ein minimum reduzieren. Aber egal, das war nicht mehr die Frage an sich... |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Also ich vermute mal, ein Integer/Cardinal wird in einem 64-Bit-System 64 Bit groß sein.
Da ein Prozessor immer darauf optimiert ist, mit Zahlentypen in seiner Wortbreite zu arbeiten, sollte man also Integer/Cardinal verwenden, da diese ja gerade immer in Wortbreite sind. (Wenn CodeGear sinnvoll handelt) Die anderen Datentypen mit fester Größe sind vor allem dann wichtig, wenn die Größe wichtig ist. Das kann bei DLL-Aufrufen so sein, oder wenn man irgendwas per Netzwerk verschickt oder auch in eine Datei speichert. Wenn man da z.B. statt LongWord einfach Cardinal schreibt und das Programm dann mit einem 64 Bit-Delphi kompiliert, kracht das natürlich, wenn man eine Datei von der 32 Bit-Version einliest. Also: Wenn die Größe wichtig ist, sollte man die Typen ShortInt/Byte, SmallInt/Word, LongInt/LongWord verwenden, ansonsten Integer/Cardinal. |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
@Muetze1
Wow. Danke! :thumb: Die ersten zwei Abschnitte hab ich gelesen. Aber ich werde mir das morgen noch einmal in Ruhe beim Frühstück zu Gemüte führen. Vielen Dank an alle für Eure Bemühungen. Gute Nacht. |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Zitat:
Zitat:
Also noch mal Danke an alle. |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Zitat:
![]() Ich glaube doch eher, dass CodeGear Micorosofts Beispiel folgt, da sie für deren Betriebssystem Code erzeugen. Und es wäre doch schon etwas dumm, wenn ein C++ "int" nicht dem Delphi "Integer" entspräche. |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Welchen Sinn hätte es sonst, dass es einerseits ein LongWord und einen Cardinal gibt? Ich meine, wenn ich eine portierbare Anwendung schreiben will, dann ist es nützlich, einen Zahlendatentypen zu haben, der Wortbreite hat.
Und dass ein Integer nicht das gleiche ist wie ein int, naja, was ist so schlimm daran? Ein String in Delphi ist auch kein String in C und ein Byte/Char in Delphi muss (gemäß Standard) auch nicht unbedingt ein char in C sein. Sogar bei Booleans gibt man ja in Delphi, wenn man eine DLL importiert, nicht "Boolean" an, sondern "LongBool". Ich würde es für sehr sinnvoll halten, wenn es weiterhin so bleibt: Es gibt zwei ordinale Datentypen, die immer Wortbreite haben, jeweils einer vorzeichenbehaftet und einer nicht und dann je zwei ordinale Datentypen für jede Zweierpotenz von Bytes darunter. |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Aber sehr wahrscheinlich benutzt jede Anwendung, die Daten in Dateien ablegt, für Vierbytezahle Cardinal oder Integer statt Longint und Longword. All diese Programme würden dadurch schwerer portierbar (solche Fehler zu finden ist schwer...).
|
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Was wiederum völlig egal ist, solange diese älteren Programme nicht mit einem neueren Compiler übersetzt werden, der die neue Wortbreite zu Grunde legt. Bestehende Executables und DLLs sind also genausowenig davon betroffen, wie Übersetzungen mit 32 Bit Compilern, womit die Menge des Codes der dahingehend geändert werden müsste ganz erheblich schrumpft. Ich bin durchaus der Meinung, dass man diesen Umstand sehr wohl einer einheitlichen und eindeutigen Nomenklatur dulden kann. Im zweifel rauscht man einfach durch den alten Code, und ersetzt alle Integer-Deklarationen durch LongInt, und hat wieder das alte Verhalten mit quasi null Aufwand. Die durch die inkonsequente Namensgebung entstehenden Missverständnisse stehen dazu imho in keinem Verhältnis. Ich seh ja schon die Foren überquellen :lol:
Und wo dann dennoch Speed gefragt ist, was Deklarationsabhägig nicht so häufig der Fall sein dürfte, ist es imho auch nicht zu viel verlangt die paar Schleifenvariablen o.ä. von Hand auf den wortbreiten Typ zu ändern, nachdem man den restlichen Code per Suchen und Ersetzen angepasst hat. Aber eine Bezeichnung von ehemals generischen Typen auf eine feste Länge zu setzen, halte ich schon allein aus irgenwie ästhetischen Grunden für... mh, mistig :) |
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
@Dax: Das sollte eigentlich nicht so sein, dass Integer und Cardinal generisch sind, ist schließlich weithin bekannt. Wenn also ein Programm für solche Zwecke diese Typen nutzt, würde ich einfach behaupten, es ist schlecht geschrieben.
|
Re: Integer-Datentypen - DH empfiehlt immer Integer oder Car
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz