uint64_t im ATmega8

Gast #3304305
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.
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
Gast
...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...
(Firma: guloshop.de)
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)
Gast
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.