mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Was ist die schnellere Operation?


Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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... :-/

Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreiben will ich in C mit Eclipse.

Autor: X- Rocka (x-rocka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Udo Schmitt (urschmitt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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]

Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Udo Schmitt (urschmitt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry ich verstehs nicht, welche Teile von dem Code sollen gleich sein?
Kann jetzt aber auch nicht mehr weiter reinschauen, muss arbeiten, 
sorry.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: AVR-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Herbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: <yxcvbnm,.- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yep, ich ging davon aus, dass sich die Frage auf I/O-Ports bezieht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.