Hallo, kurze Frage zum ATmega8. Hab in einem Programm ein uint64_t verwendet und dann eine Funktion der Art geschrieben, dass überprüft wird, ob ein Bit in einer langen Zahl gesetzt ist, oder nicht: uint64_t Datensatz = (irgendeine_Zahl); for(j=0; j<64; j++) { uint64_t Var = 1; Var = (Var<<j); if(Var = Datensatz) {mache etwas} else {mach was anderes} } ...nur irgendwie ist die Funktion tierisch langsam, so dass ich eigentlich den uint64_t im Verdacht habe das Problem zu begünstigen. Ist das realistisch?
"Tierisch" ist ein dehnbarer Begriff, aber ja: uint64_t ist vergleichsweise sehr langsam auf AVR. Aber immer noch schneller, als von Hand, also eher "unmenschlich" langsam. "Tierisch" trifft es dann ganz gut. P.S.: Shiften ist auf AVR ohnehin nicht der Bringer, was Geschwindigkeit angeht.
sorry, ich meinte natürlich in der if-Abfrage das einfache &: if(Var & Datensatz) ...
Am besten ist entweder, auf lange Zahlen zu verzichten (was vielleicht kein guter Rat ist; schließlich wirst du einen Grund dafür haben), oder du machst dir ein Feld mit 64 Bitmasken: im ersten Element ist das unterste Bit gesetzt, im zweiten das nächste usw., und statt bei jedem Test die 1 entsprechend weit zu schieben, nimmst du nur das [i]-te Element aus dem Feld. Dann hast du in 64 Bit immerhin nur einen Vergleich, was schon schneller gehen wird.
@atmega (Gast) >ich meinte natürlich in der if-Abfrage das einfache &: >if(Var & Datensatz) Was ist für dich "tierisch langsam" ? Man muss 8 Bytes jeweils miteinander vergleichen, das dauer halt mal wenigsten 8 Takte für die Vergleiche und je einen Takt pro bedingtem Sprung, macht wenisgten 16 Takte. Dazu ggf. noch das Lade in die richtgen Register, macht in Summe vielleicht 30-50 Takte. Solche 64 Bit Operationen sind nicht die Kernkompetenz von 8 Bit Controllern. Hier ist es oft sinnvoller und leistungsfähiger, die Daten als Array von Bytes zu betrachten und zu verarbeiten.
Hallo. Mir ist vor einer ganze Weile mal aufgefallen, das mein AVR-gcc fuer ein einfaches 64Bit Increment einen abartig langen und komplizierten Maschienencode generiert. Seh dir mal den fertigen Code deiner Firmware an (objdump). Vermutlich kannst du ein wenig Performance/Codegroesse durch "manuelles compilieren" via "naked" functions und inline assembler herauskitzeln - wenn du es dir zutraust... MfG
...also ich wollte damit ein Signal generieren. Der Code innerhalb der if/else Anweisung sollte eigentlich nicht länger als 15us dauern. Die gesamte for-Schleife zeigt mir aber eine Durchlaufzeit von mehr als 200ms, so dass der zusätzliche Zeitbedarf wohl aus dem Schieben und dem eigentlichen Vergleich herrührt, jedenfalls ist dies meine Vermutung. Schön, dass andere ähnliche Erfahrungen mit dem uint64_t gesammelt haben...
Hallo! atmega schrieb: > Var = (Var<<j); Das dauert – wie schon geschrieben wurde – recht lange. Ich würde Var lieber global definieren und in der Schleife immer nur um 1 Bit verschieben: Var<<= 1; > if(Var = Datensatz) Gemeint hast du bestimmt das hier: if(Var == Datensatz)
>> if(Var = Datensatz) >Gemeint hast du bestimmt das hier: > if(Var == Datensatz) ne, gemeint war if(Var & Datensatz)
atmega schrieb: > ne, gemeint war > > if(Var & Datensatz) Sicher? Nicht eher
1 | if (Var && Datensatz) |
Frank
Frank schrieb: > Sicher? Nicht eher > if (Var && Datensatz) > > Frank Vergiss es .... (Var & Datensatz) past schon ...
2 Ideen, die vielleicht helfen könnten: 1: Union benutzen und auf die einzelnen Bytes zugreifen 2: Auf Variable Var verzichten
1 | union { |
2 | uint64_t Datensatz; |
3 | unit8_t Bytes[8]; |
4 | }
|
5 | |
6 | for(j=0; j<8; j++) { |
7 | for(k=0; k<8; k++) { |
8 | if (Bytes[j] & (1<<k)) { |
9 | machewas; |
10 | }
|
11 | else { |
12 | machewasanderes
|
13 | }
|
14 | }
|
15 | }
|
@ atmega (Gast) >...also ich wollte damit ein Signal generieren. Also ein Array von Daten bitweise rausschieben. Das macht man deutlich besser mit einem Bytearray, wie bereits gesagt. >Der Code innerhalb der if/else Anweisung sollte eigentlich nicht länger >als 15us dauern. Die gesamte for-Schleife zeigt mir aber eine >Durchlaufzeit von mehr als 200ms, so dass der zusätzliche Zeitbedarf >wohl aus dem Schieben und dem eigentlichen Vergleich herrührt, >jedenfalls ist dies meine Vermutung. Das ist kein echter Code, nur ein hingeschriebenes Fragment. Poste den Originalcode OHNE Abschreiben als Anhang.
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.