Hallo, ich habe folgendes Problem: Wenn ich zu einem uint8_t einen festen Wert addiere übersetzt mein Compiler(arm-none-eabi-gcc) das zu einer Integerrechnung. Für mich ist es aber wichtig, dass es ein uint8_t bleibt. Sonst drohen Zugriffe auf undefinierte Speicherabschnitte. Beispiel: int32_t Array[256]; uint8_t ZaehlVariable; int32_t Variable; Variable = Array[ZaehlVariable+20]; In diesem Beispiel wird die 20 als Integer erkannt und die Rechnung als Integerrechnung durchgeführt und damit wird auch das Ergebnis ein Integer. Für float-Wert kenne ich die Möglichkeit 3.14f zu schreiben (für unsigned int 20u, für unsigned long 20ul) damit der Compiler das richtige Format an nimmt und zur Richtigen Instruktion übersetzt. Gibt es das auch für char (z.B. 20uc)? Einen Cast Variable = Array[(uint8_t)(ZaehlVariable+20)]; möchte ich nicht machen, denn das Übersetzt der Compiler zu einer Integerrechnung und einem Cast, was ein zusätzlicher Rechenschritt ist. Hierfür gibt es doch sicher eine einfache, elegante Lösung. Vielen Dank schon mal im voraus.
Sebastian schrieb: > Einen Cast Variable = Array[(uint8_t)(ZaehlVariable+20)]; möchte ich > nicht machen, denn das Übersetzt der Compiler zu einer Integerrechnung > und einem Cast, was ein zusätzlicher Rechenschritt ist.
1 | Variable = Array[(ZaehlVariable+20) & 0xFF]; |
Ob das nun besser als ein Cast ist, musst du selbst entscheiden.
Sebastian schrieb: > Einen Cast Variable = Array[(uint8_t)(ZaehlVariable+20)]; möchte ich > nicht machen, denn das Übersetzt der Compiler zu einer Integerrechnung > und einem Cast, was ein zusätzlicher Rechenschritt ist. Ein cast ist in dem Fall kein zusätzlicher Rechenschritt. Allerdings ist nunmal in C ein Arrayindex per Definition ein Integer, daran kannst du auch mit casten nichts ändern. Es geht aber so:
1 | uint8_t tmpIndex = ZaehlVariable + 20; |
2 | Variable = Array[tmpIndex]; |
Oliver
Sebastian schrieb: > Einen Cast Variable = Array[(uint8_t)(ZaehlVariable+20)]; möchte ich > nicht machen, denn das Übersetzt der Compiler zu einer Integerrechnung > und einem Cast, was ein zusätzlicher Rechenschritt ist. Hast du das im Assemblerlisting nachgesehen? Oder rätst du nur? Es ist sowieso klar, dass ein 32 Bit Prozessor jede Rechnung mit 32 Bit ausführt. Du kannst nur bestimmen, welchen Teil des Ergebnisses du hinterher verwenden willst...
Sebastian schrieb: > Einen Cast Variable = Array[(uint8_t)(ZaehlVariable+20)]; möchte ich > nicht machen, denn das Übersetzt der Compiler zu einer Integerrechnung > und einem Cast, was ein zusätzlicher Rechenschritt ist das optimiert er doch weg.
1 | Variable = Array[(ZaehlVariable+20)&0xFF]; |
sollte auch gehen.
Lothar M. schrieb: > Es ist sowieso klar, dass ein 32 Bit Prozessor jede Rechnung mit 32 > Bit ausführt. Eben. Bei Rechnungen in kleineren Einheiten kostet das beim STM32 eher mehr Zeit. Entsprechende Tests habe ich schon gemacht. Seitdem habe ich bei Source-Portierungen von AVR nach STM32 sehr viel Gefallen an den uint_fastXt Typen gefunden. So bleibt der Source portabel und der STM32 kann trotzdem mit Vollgas arbeiten - solange man Überläufe nicht implizit ausnutzt, wie der TO das will. Ich halte das für unsauber. Besser wäre dann eine explizite Maskierung mit 0xFF.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Besser wäre dann eine explizite Maskierung mit 0xFF. Allemal. Und optimiert wird diese Berechnung dann sowieso...
Vielen Dank für die schnellen Antworten. die Möglichkeit das Ergebnis mit einer &-Operation zu begrenzen Variable = Array[(ZaehlVariable+20)&0xFF]; ist im Endeffekt das gleiche wie der Cast Variable = Array[(uint8_t) (ZaehlVariable+20)];. Allerdings ist in beiden Fällen ein weiterer Rechenschritt notwendig. Ich 320 dieser Rechnungen in einem engen Rahmen zu machen und der zusätzliche Rechenschritt erhöht meine Durchlaufzeit um mehr als 10%. Ich hatte gehofft ich kann das umgehen in dem ich dem Compiler die Art seiner Rechnung von vornerein vorgeben kann.
Sebastian schrieb: > Allerdings ist in beiden Fällen ein weiterer Rechenschritt notwendig. nein nicht wirklich. Schau dir den ASM-Code an, dann sieht du was wirklich passiert. Wenn man dir Sagt das du die letzte stelle von 1234 nennen sollte, rechnest du auch nicht.
Bei Array[256] ist aber max(uint8_t)+20 auch außerhalb. Das funktioniert also auch nicht "implizit", sonder ist schlicht buggy Code. Und zwar auf jeder Plattform.
Lothar M. schrieb: > Hast du das im Assemblerlisting nachgesehen? Oder rätst du nur? Ich habe die Durchlaufzeiten gemessen und es ist eindeutig, dass die Zeiten mit dem Cast länger werden.
Sebastian schrieb: > Ich habe die Durchlaufzeiten gemessen und es ist eindeutig, dass die > Zeiten mit dem Cast länger werden. Gegenüber welchem Code? Der ohne Cast ist falsch, den kanst du also nicht als Referenz nehmen. Du kannst nur den Code mit Cast mit dem mit & vergleichen. Oder, wenn es so zeitkritisch ist, Assembler nehmen. Hast du die Optimierung an? Welche?
Was eigentlich gewünscht ist:
1 | Array[(ZaehlVariable+20)%256]; |
Das das per "&0xFF" geht, bekommt der Compiler selber hin. Es bleibt aber richtig, wenn die Array-Größe mal nicht 256 sein sollte.
Carl D. schrieb: > Array[(ZaehlVariable+20)%256];Das das per "&0xFF" geht, bekommt der > Compiler selber hin. Es bleibt > aber richtig, wenn die Array-Größe mal nicht 256 sein sollte. Wenn schon, denn schon:
1 | Array[(ZaehlVariable + 20) % (sizeof(Array) / sizeof(*Array))]; |
:
Bearbeitet durch User
Sebastian schrieb: > uint8_t ZaehlVariable; Sebastian schrieb: > Ich habe die Durchlaufzeiten gemessen und es ist eindeutig, dass die > Zeiten mit dem Cast länger werden. Dann versuche, uint8_t generell und insbesondere bei Zählvariablen zu vermeiden! Nimm uint_fast8t. Damit laufen zum Beispiel Schleifen über die Zählvariablen um einiges schneller. Allerdings musst Du dann alle bisher implizit einkalkulierten Überläufe selber mit & 0xFF in Ordnung bringen, da auf dem STM32 ein uint_fast8t denselben Wertebereich wie ein uint32_t hat.
:
Bearbeitet durch Moderator
@Dirk B: Du hast recht ich habe es mit dem falschen Code, ohne Cast verglichen. Hier rechnet er über das Array hinaus, aber schnell. Das mit dem uint_fast8_t wird ich mir ansehen, das habe ich noch nicht benutzt. Wenn das nicht klappt werde ich wohl den Cast oder das &0xFF nehmen und wenn es zum Schluss zeitlich nicht reicht werde ich es mal mit Assembler versuchen.
Sebastian schrieb: > Das mit dem uint_fast8_t wird ich mir ansehen, das habe ich noch nicht > benutzt. uint_fast8_t benutzt immer den Typ, mit dem der konkrete µC am schnellsten rechnen kann. Auf dem STM32 ist es identisch mit uint32_t, auf einem ATmega oder ATtiny ist es identisch mit uint8_t. Das heisst konkret für den STM32: Er rechnet in 32-Bit sauschnell. Allerdings ist ein Wert größer als 255 durchaus möglich. Dem musst du selbst vorbeugen. Du fragst Dich sicher: "Warum soll ich denn dann nicht direkt uint_32t nehmen". Für mich gibt es da 2 Gründe: 1. Mnemotechnisch: Du sagst dem Leser des Codes: Das ist eine Variable, deren Wertebereich bis 255 geht. Allerdings muss ich mich selber drum kümmern, dass dieser Wertebereich auch eingehalten wird. 2. Portabilität: Von 8-Bit bis 32-Bit µC sauschnell
:
Bearbeitet durch Moderator
Peter II schrieb: >> Allerdings ist in beiden Fällen ein weiterer Rechenschritt notwendig. > > nein nicht wirklich. Schau dir den ASM-Code an, dann sieht du was > wirklich passiert. Hier ist ein ARM am Werk, kein AVR oder x86. Und ein ARM kann nicht mit 8 Bits rechnen. Der rechnet immer mit 32 Bits und muss ggf. anschliessend maskieren. Was immer der TE also macht, die effiziente reine 8-Bit Rechnung, die er sich vorstellt, wird er nicht kriegen. Nicht in C, aufgrund der Sprachdefinition, aber auch nicht in Assembler. Es ist daher schon so wie Frank schreibt. Wenn man versucht, jedes einzelne Zwischenergebnis auf 8 Bits runterzubrechen, egal ob per Variablendeklaration oder Cast, schmeisst man dem Compiler bloss Knüppel zwischen die Beine. Denn das kostet.
:
Bearbeitet durch User
@A.K. sehr präzise Antwort Ich werde es jetzt mit der Maskierung machen. Vielen Dank an alle.
Frank M. schrieb: > 2. Portabilität: Von 8-Bit bis 32-Bit µC sauschnell Richtig. Für Grössenangaben, also z.B. für einen Index eines Arrays, würde ich jedoch size_t empfehlen. Da der Operator sizeof auf jedes Objekt angewandt werden kann und sein Ergebnis als size_t liefert, kann kein Objekt im Speicher, auch kein Array, mehr als SIZE_MAX Bytes belegen.
:
Bearbeitet durch User
Portabel bedeutet auch, daß man hinschreibt, was man meint. Ein Array als "Ringpuffer" zu betreiben, indem man auf das Überlaufverhalten einer Variable hofft, taugt nichts. Wenn man Dinge wie "2^n" als Arraygröße ausnutzen will, dann schreibt man das in den Kommentar, den Code aber so, daß er mit jeder Größe funktioniert. Und wenn ein Compiler damit nicht umgehen kann, sprich 2^n nicht erkennt, dann sollte man sich einen besseren suchen.
be s. schrieb: > Für Grössenangaben, also z.B. für einen Index eines Arrays, > würde ich jedoch size_t empfehlen. Das halte ich für nicht optimal. size_t ist auf einem AVR 16 Bit groß. Das heisst, ich sollte nach Deiner Vorstellung eine Indexvariable vom Typ uint_16t nehmen. Das wäre auf einem AVR aber längst nicht die optimale Wahl, wenn mein Array eine Größe von weniger als 256 Elementen hat.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Das halte ich für nicht optimal. size_t ist auf einem AVR 16 Bit groß. > Das heisst, ich sollte nach Deiner Vorstellung eine Indexvariable vom > Typ uint_16t nehmen. Das wäre auf einem AVR aber längst nicht die > optimale Wahl, wenn mein Array eine Größe von weniger als 256 Elementen > hat. Da hast du natürlich recht. Andererseits programmiere ich lieber portabel, als dass ich voreilige Optimierungen vornehme, die wahrscheinlich gar nicht nötig sind. Bisher hatte ich noch nie das Problem, dass aufgrund eines 16Bit statt 8Bit Indizes das Programm zu langsam war oder nicht mehr in den Programmspeicher passte. Sollte es aber jemals nachweislich daran scheitern, würde ich diese Handoptimierung nicht scheuen (zumal sie wahrscheinlich nur an ein, zwei Stellen nötig wäre).
:
Bearbeitet durch User
be s. schrieb: > Bisher hatte ich noch nie das > Problem, dass aufgrund eines 16Bit statt 8Bit Indizes das Programm zu > langsam war oder nicht mehr in den Programmspeicher passte. Möglicherweise bist du von AVRs verwöhnt. Schon mal mit grösseren Datentypen auf einer 8-Bit Akkumulator-Architektur in C gearbeitet? Selbst wenn das in Platz und Zeit reicht kriegt man mitunter Hirnkrämpfe, wenn man den erzeugten Code anschaut. Besonders bei solchen Zierden wie den 12/14-Bit PICs.
be s. schrieb: > Andererseits programmiere ich lieber portabel Das mache ich auch, versuche aber trotzdem optimalen Code zu erreichen. Und das geht! Eine Verwendung einer 16-Bit-Variablen als Index ist für mich in 99% aller Fälle ein No-Go. Die käme für mich tatsächlich nur in Frage, wenn das Array mehr als 255 Elemente hat. Aber wann ist das schon so? Ich kann beim besten Willen keine Portabilität beim Verwenden eines size_t für Indexvariablen von Arrays erkennen. Magst Du mir diese erläutern? (Das Argument, dass size_t wegen SIZE_MAX Bytes immer jedes theoretisch noch so große Array abdeckt, ist für mich keines. Denn es gibt in den meisten Fällen gar keine "theoretisch noch so große Arrays". In den allermeisten Fällen sind sie wesentlich kleiner.) Vielleicht verwechselst Du Portabilität mit Codesicherheit?
:
Bearbeitet durch Moderator
Frank M. schrieb: > Das halte ich für nicht optimal. size_t ist auf einem AVR 16 Bit groß. > Das heisst, ich sollte nach Deiner Vorstellung eine Indexvariable vom > Typ uint_16t nehmen. Das wäre auf einem AVR aber längst nicht die > optimale Wahl, wenn mein Array eine Größe von weniger als 256 Elementen > hat. Bin mir nicht sicher, ob auch deine 8bit nicht als 16bit übergeben werden. Intern ist es eine Addition mit Adressen. Die wird immer mit int gerechnet.
Peter II schrieb: > Bin mir nicht sicher, ob auch deine 8bit nicht als 16bit übergeben > werden. Intern ist es eine Addition mit Adressen. Die wird immer mit int > gerechnet. Du hast das im falschen Kontext gelesen. Wir sind da schon weiter, bitte genauer lesen. Meine Formulierung war nicht auf das Problem des TOs bezogen, sondern auf Stuckis Aussage, man solle generell size_t als Typ für Indexvariablen nehmen. Das halte ich - speziell auf AVRs - für suboptimal.
Frank M. schrieb: > Denn es gibt in den > meisten Fällen gar keine "theoretisch noch so große Arrays". "640 kB ought to be enough for anybody."
Frank M. schrieb: > Ich kann beim besten Willen keine Portabilität beim Verwenden eines > size_t für Indexvariablen von Arrays erkennen. Der "Vorteil" ist eher Gewöhnung aus der PC-Programmierung. Die STL-Container geben halt alle ihre Größenangaben in size_t zurück, und spätestens bei der Compilierung für 64-Bit haut einem der Compiler begründete Warnungen um die Ohren, wenn man die mit Integern vermischt. Dann landet man zwangsweis dabei, für solche Größen den dafür gedachten size_t und seine Verwandten zu verwenden. Oliver
Peter II schrieb: > Bin mir nicht sicher, ob auch deine 8bit nicht als 16bit übergeben > werden. Intern ist es eine Addition mit Adressen. Die wird immer mit int > gerechnet. Nicht die Adressrechnung selbst ist davon wesentlich betroffen, denn die läuft immer in size_t. Der Kram drumherum jedoch kann es sein, also die Handhabung vom Index ausserhalb der eigentlichen Adressierung. Je nach Umgebung ist mal dies mal jenes besser. Mit uint_fast8_t liegt man stets auf der effizienten Seite, mit size_t nicht überall.
:
Bearbeitet durch User
A. K. schrieb: > Möglicherweise bist du von AVRs verwöhnt. Schon mal mit grösseren > Datentypen auf einer 8-Bit Akkumulator-Architektur in C gearbeitet? > Selbst wenn das in Platz und Zeit reicht kriegt man mitunter > Hirnkrämpfe, wenn man den erzeugten Code anschaut. Besonders bei solchen > Zierden wie den 12/14-Bit PICs. Ich hab mit den alten 16er PICs angefangen, nicht ohne Grund habe ich die alten PICs (10/12/16/18) hinter mir gelassen. Da gibt es noch ganz andere Fallstricke wie z.B. ein 8-stufiger Hardwarestack (alte 16er, vergiss den Interrupt nicht...). Die neueren 18er sind eher wieder gut zu gebrauchen, die 24er und 32er habe ich nie verwendet, diese fallen aber so oder so in eine andere Kategorie. Frank M. schrieb: > Eine Verwendung einer 16-Bit-Variablen als Index ist für > mich in 99% aller Fälle ein No-Go. Die käme für mich tatsächlich nur in > Frage, wenn das Array mehr als 255 Elemente hat. Aber wann ist das schon > so? Wenn ich eine Bibliothek schreibe, die mit übergebenen Arrays hantiert, kann ich zum Voraus unmöglich wissen, wie gross das Array ist. Die gesamte Bibliothek umschreiben, nur weil ich diese später auf einem grösseren uC oder auf dem PC mit Arraygrössen > 256 nutzen will? Nein Danke. Für ein lokales Array bin ich mit dir einverstanden, da kann man sowas machen, ich tus nicht.
Oliver S. schrieb: > Der "Vorteil" ist eher Gewöhnung aus der PC-Programmierung. Ja, den "Vorteil" sehe ich natürlich ein. Für einen PC oder Server programmiere ich auch ganz anders. Da bringt es überhaupt nichts, mit uint_fast8 zu kleckern. Ich käme da auch nie in den Sinn, so etwas zu nutzen. Allerdings habe ich auch schon Programme geschrieben, die auf einem AVR, Linux und auch Windows laufen. Dann wird gekleckert, sonst geklotzt. Wobei man "Klotzen" jetzt nicht mit Speicherverschwendung verwechseln sollte. Es kommt immer drauf an, ob man auf bestimmte Zielplattformen Rücksicht nehmen muss oder nicht. Handelt es sich beispielsweise um ein STM32-Programm, welches niemals auf einen 8-Bit-µC portiert werden wird: Scheiss auf uint_fast8t. Nimm direkt int oder unsigned int oder auch speziell bei Indexvariablen size_t.
:
Bearbeitet durch Moderator
A. K. schrieb: > Mit uint_fast8_t liegt man stets > auf der effizienten Seite, mit size_t nicht überall. Korrektur: Stimmt leider auch nicht. Da mindestens in Linux auf einer 32/64-Bit Kiste mit 8-Bit Operationen wie x86(-64) der Typ uint_fast8_t mit 8-Bits definiert ist, ist man da mit size_t besser dran als damit. Das Ei des Kolumbus gibts dafür also nicht.
Frank M. schrieb: > Handelt es sich beispielsweise um ein > STM32-Programm, welches niemals auf einen 8-Bit-µC portiert werden > wird: Scheiss auf uint_fast8t. Nimm direkt uint32_t. Das sehe ich anders, ist sicher aber auch Geschmackssache. Warum sollte ich für eine Membervariable einer Klasse etwas anderes als uint_least8_t verwenden, wenn ich nur die Werte 0, 1, 2 und 3 speichern muss? Ja ich weiss, es gibt Plattformen, bei denen solche Speicherzugriffe extremst ineffizient sind. Andererseits könnte die Klasse auch X-Mal im Speicher liegen, dann machts schon einen Unterschied, ob 1M * 1Byte oder 1M * 4Byte (je nach Plattform natürlich). Aber es ist so wie mit allem, allen kann mans nicht rechtmachen.
be s. schrieb: > Wenn ich eine Bibliothek schreibe, die mit übergebenen Arrays hantiert, > kann ich zum Voraus unmöglich wissen, wie gross das Array ist. Das ist korrekt. Außer es gibt schon technische Beschränkungen, die eine obere Grenze vorgeben. Aber wie A.K. schon zitierte: "640 kB ought to be enough for anybody." Da hat er Recht - und damit Du auch.
be s. schrieb: > Das sehe ich anders, ist sicher aber auch Geschmackssache. Warum sollte > ich für eine Membervariable einer Klasse etwas anderes als uint_least8_t > verwenden, wenn ich nur die Werte 0, 1, 2 und 3 speichern muss? Aufgrund des möglicherweise zusätzlichen Aufwands für den Umgang mit 8-Bit Daten in lokalen Variablen? Es hängt also von der Verwendung ab. Im Speicher minimieren, im Register an den Maschinenworten orientieren.
:
Bearbeitet durch User
A. K. schrieb: > Da mindestens in Linux > auf einer 32/64-Bit Kiste mit 8-Bit Operationen wie x86(-64) der Typ > uint_fast8_t mit 8-Bits definiert ist, ist man da mit size_t besser > dran als damit. Habe es gerade mal geprüft. Tatsächlich ist dem so: sizeof (uint_fast8_t) ist unter Linux (32/64) tatsächlich 1. Verstehen kann ich das nicht. Siehst Du dafür einen Grund? > Das Ei des Kolumbus gibts dafür also nicht. Korrekt.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Siehst Du dafür einen Grund? warum sollte auf einem x68 64bit schneller als 8bit sein? mehrere 8bit Operationen können gleichzeitig gemacht werden.
Frank M. schrieb: > Verstehen kann ich das nicht. Siehst Du dafür einen Grund? Bei uint_fast8_t stand offenbar nicht die Verwendung als Index im Vordergrund, sondern der normale Umgang bei Rechnungen, Vergleichen etc. Und da ist x86 bei Skalaren neutral.
:
Bearbeitet durch User
Peter II schrieb: > warum sollte auf einem x68 64bit schneller als 8bit sein? Bei der hier im Thread erfolgten Verwendung als Array-Index entsteht zusätzlicher Aufwand durch die erforderliche Erweiterung.
A. K. schrieb: > Bei der hier im Thread erfolgten Verwendung als Array-Index entsteht > zusätzlicher Aufwand durch die erforderliche Erweiterung. bei x86 kann man doch auch 64 und 8 bit addieren. Da muss doch vorher nicht erweitert werden.
Peter II schrieb: > bei x86 kann man doch auch 64 und 8 bit addieren. Wie? Ausserdem wird diese Rechnung meist in der Adressierung selbst durchgeführt, und die kennt keine 8-Bit Register. Bei x86-64 sind das trotz 32-Bit int/unsigned 64-Bit Register. Hier lässt GCC deshalb 2 Indizes parallel laufen, einer mit 32 fürs Zählen und einer mit 64 Bits fürs Adressieren, weil i negativ sein kann:
1 | void f(int *a, int b, int n) { |
2 | int i; |
3 | for (i = b; i < n; ++i) |
4 | a[i] += 1; |
5 | }
|
Hier hingegen reicht ein Index:
1 | void f(int *a, int n) { |
2 | int i; |
3 | for (i = 0; i < n; ++i) |
4 | a[i] += 1; |
5 | }
|
:
Bearbeitet durch User
A. K. schrieb: > Und da ist x86 bei Skalaren neutral. Habe ich gerade mal durch einen kleinen selbstgehackten Benchmark auf x86-64 (Linux) verifiziert. Du hast recht. Beim x86 ist das tatsächlich so. Kenne ich von anderen 32- oder 64-Bit-Plattformen (diverse RISC-CPUs) anders. Ist das der x86-typischen Altlast geschuldet?
:
Bearbeitet durch Moderator
Frank M. schrieb: > Kenne ich von anderen 32- oder 64-Bit-Plattformen (diverse > RISC-CPUs) anders. RISCs haben vom Prinzip her nur Wortoperationen in Registern. Bei 64 Bit Architekturen aber u.U. auch noch 32 Bit Operationen, um beim (L)LP64 Modell (32 Bit int/unsigned) keinen zusätzlichen Aufwand zu bekommen. Aber weder 8 noch 16 Bits. ARM hatte Anfangs noch nicht einmal Lade- und Speicheroperationen für 16 Bit Typen. > Ist das der x86-typischen Altlast geschuldet? Ja. 8086 hatte gleichermassen 8- wie 16-Bit Operationen. Die haben sich erhalten, so dass x86-64 gleichermassen mit 8, 16, 32 und 64 Bits rechnen kann. Bei der Division kann sich ein kleinerer Type auch sehr lohnen und in der Codierung gibts einen kleinen Vorteil bei 8 und 32 Bits. Es kann allerdings subtile Laufzeitunterschiede durch die Implementierung geben. Etwa wenn ein Prozessor bei Teilwortoperationen (8 und 16 Bits) den Rest des Registers mit durch die ALU schiebt und sich dabei ggf. falsche Abhängigkeiten einhandelt.
:
Bearbeitet durch User
A. K. schrieb: > lässt GCC deshalb 2 Indizes parallel laufen, einer mit 32 fürs Zählen > und einer mit 64 Bits fürs Adressieren, weil i negativ sein kann: Das war Unsinn. Komplizierter als mit 64-Bit Variablen ist der Code aber trotzdem. Zumal er (4.7.2) bei unsigned als Indextyp die implizite zero-extension von 32 Bit Operationen nicht optimal nutzt.
:
Bearbeitet durch User
A. K. schrieb: > Peter II schrieb: >> bei x86 kann man doch auch 64 und 8 bit addieren. > > Wie? Würde mich auch interessieren. Opcode?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.