Hallo, ich hätte da mal eine Frage zur Abarbeitung einiger Befehle. Bits setzen per define: #define setzen1 11001100 #define setzen2 11001011 reg1 = setzen1; [Something to do] reg1= setzen2; [Something to do] reg1 = setzen1; bits setzen durch log. Ops: reg1= 11001100; [something to do] reg1 &= ~(1<< 2); reg1 |=11; [something to do] reg1 &= ~((1<<1)|(1<<0)); reg1 |= (1<<2); oder (falls das überhaupt geht): reg1= 11001100; [something to do] reg1^=((1<<2) | (1<<1) | (1<<0)); Meine Frage nun, sofern die Operationen funktionieren, welche davon verwendet man am Häufigsten bzw. welche ist die schnellste? Und: Bitte um Korrektur, wenn ich Operationen falsch umgesetzt habe. Vielen Dank für eure Hilfe. gruß Herbie
Herbie schrieb: > welche ist die schnellste? Wofür? Welche Zielplattform? Z.B. ist ein Formel-1 Rennwagen der schnellste auf der Straße, aber auf dem Feld ist ein Traktor schneller... :-/
Oh, entschuldigung. Ich meinte, welche Operation ist auf einem Mikrocontroller der ATMega-Serie (AVR) am Schnellsten durchzuführen? Z.B. als Interrupt-Operation. Da sollen die Befehle ja möglichst schnell abgearbeitet werden. In dem Register sollen halt nur ein paar Bits umgeschrieben werden. Danke für den Hinweis.
Kompiliere es doch mal und schau dir das listing / assembler an. Generell ist es schneller, wenn reg = const als reg = (viele logische ops). Andererseits sieht das der Compiler vielleicht und macht ne Konstante draus...
Ich verstehe ehrlich gesagt die Frage nicht so richtig. Die beiden Teile sind nicht äquivalent, sie machen unterschiedliche Dinge. Die 3 Zuweisungen sind bestimmt nicht so zeitkritisch, daß Du hier über eine Optimierung nachdenken müsstest. Interessant ist da eher der Teil [something to to]
Udo Schmitt schrieb: > Die beiden Teile sind nicht äquivalent, sie machen unterschiedliche > Dinge. Die 3 Teile sollten eigentlich alle das Gleiche machen. Herbie schrieb: > reg1= 11001100; > [something to do] > reg1^=((1<<2) | (1<<1) | (1<<0)); Da habe ich noch vergessen: [something to do] reg1^=((1<<2) | (1<<1) | (1<<0)); (denke ich). Wo ist denn der Fehler, wenn die nicht alle das Gleiche machen?
Sorry ich verstehs nicht, welche Teile von dem Code sollen gleich sein? Kann jetzt aber auch nicht mehr weiter reinschauen, muss arbeiten, sorry.
Herbie schrieb: > Meine Frage nun, sofern die Operationen funktionieren, welche davon > verwendet man am Häufigsten bzw. welche ist die schnellste? Ich würde die Variante 1 nehmen, denn dann könnte ich einfach durch ein Ändern des #defines definierte andere Werte auf das reg1 schreiben. Bei den anderen beiden Versionen ist das wesentlich versteckter...
Das Setzen des Register reg1 soll am Ende immer gleich sein. Also zwischen den [something to do]-Abschnitten. Das erste Mal soll 11001100 in reg1 stehen. Dann kommt [something to do], danach soll 11001011 in reg1 stehen. Dann wieder [something to do] und danach soll wieder 11001100 in reg1 stehen. Udo Schmitt schrieb: > Kann jetzt aber auch nicht mehr weiter reinschauen, muss arbeiten, > sorry. Ok, danke für deine Hilfe. Viel Spaß beim Arbeiten.
Ich würde das Ganze im Simulator vom AVR-Studio ablaufen lassen. Da gibt es für die Zeit und die Anzahl der Zyklen eine gute Anzeige, kann man sogar rücksetzen.
Lothar Miller schrieb: > Ich würde die Variante 1 nehmen, denn dann könnte ich einfach durch ein > Ändern des #defines definierte andere Werte auf das reg1 schreiben. > Bei den anderen beiden Versionen ist das wesentlich versteckter... Danke sehr. Die andern beiden Versionen wären halt variabel; aber defines sind übersichtlicher. Wäre denn die 1. Variante auch am Schnellsten oder tun die sich da alle nicht viel?
AVR-Fan schrieb im Beitrag #1965931: > Ich würde das Ganze im Simulator vom AVR-Studio ablaufen lassen. Das habe ich leider nicht. Also ich kann es nicht über die Entwicklungsumgebung testen. (Zumindest momentan nicht)
ein blick in die assembler-doku hilft weiter bezgl der ausführungszeiten. da ein c-compiler mit unterschiedlichen optimierungs-varianten arbeiten kann, ist auch der generierte assembler-code unterschiedlich. generell schlägt eine logische operation mit einem takt zu buche, genauso eine zuweisung. zusätzlich können noch stack-operationen dazukommen, da man in c nicht so viel kontrolle über die einzelnen register hat wie in assembler
> reg1 &= ~((1<<1)|(1<<0)); > reg1 ^= ((1<<2) | (1<<1) | (1<<0)); In beiden Varianten läuft das bei reg1 = I/O-Register auf laden, modifizieren, speichern als 3 getrennte Operationen raus. > reg1 |= (1<<2); Wenn reg1 im bitadressierbaren Bereich der I/O-Ports liegt, dann ist das ein einziger Befehl, somit effizienter. Wenn nicht, dann lauft das genau wie oben.
A. K. schrieb: > In beiden Varianten läuft das auf laden, modifizieren, speichern als 3 > getrennte Operationen raus. das muss aber nicht sein, die variable kann ja schon in einem Register stehen. Bzw. sie kann eine Lokale Variable sein und nur in einem Register vorhanden sein.
Yep, ich ging davon aus, dass sich die Frage auf I/O-Ports bezieht.
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.