uint64_t im ATmega8

Gast #3304305
Lesenswert?

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?
#3304317
Lesenswert?

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.
#3304323
Lesenswert?

@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.
#3304330
Lesenswert?

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 #3304355
Lesenswert?

...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...
Gast #3304398
Lesenswert?

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
  }
#3304414
Lesenswert?

@ 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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren