mikrocontroller.net

Forum: Compiler & IDEs Frage Effektivität C-Code


Autor: Manni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
als Anfänger (C, Assembler und MCU) spiele ich derzeit die einfachsten
Sachen im Atmel Studio (4.10.356 mit Mega16) durch, um zu lernen.
Folgendes kann ich nicht so ganz verstehen:

#define ALPHA 3
#define BETA 5
#define RK 2000
int RW, ADC;

int main (void)
{
  RW=(ALPHA+BETA)*RK;
  ADC=RW/10;
}

braucht in der .text-Sektion 266 und insgesamt 303 Prozessortakte zum
Endergebnis. Wenn ich statt RW die Formel zur Berechnung von RW
einsetze

#define ALPHA 3
#define BETA 5
#define RK 2000
int RW, ADC;

int main (void)
{
  RW=(ALPHA+BETA)*RK;
  ADC=(ALPHA+BETA)*RK/10;
}

braucht es in der .text-Sektion nur 184 und insgesamt nur 70
Prozessortakte. Das ist ja ein enormer Unterschied. Warum? In der
Assemblerausgabe kann ich es leider aus Unkenntnis nicht ergründen. Daß
obiges Beispiel mit Konstanten für ALPHA etc. schneller und
platzsparender ist als die Werte in Variablen zu verpacken ist
einleuchtend (auf die muß immer erst zugegriffen und der Wert geladen
werden).

Zusatzfrage: Überall habe ich gelesen, daß Kommazahlen vermieden werden
sollten, da sie irren Rechenaufwand erzeugen würden. Wenn ich aber für
ALPHA und BETA Kommazahlen nehme (z.B. 3.6 und 5.1) bleiben
Speicherverbrauch und Prozessortakte gleich ?!

Gruß

Manni

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der zweite Code enthält nur Konstanten. Die Berechnung übernimmt der
Compiler. Folglich braucht's auch keine Laufzeitroutine für Division.
Der grösste Teil des Codes ist bei einem derart winzigen Programm
ohnehin der "Wasserkopf" für Initialisierung.

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Manni!
Deine Frage in einem praktischen Beispiel.
Ich musste ein Bit togeln um zu messen, ob mein Prozesor im richtigen
Takt arbeitet. (Ich hatte da Zweifel)
In C hatte ich eine Taktfrequenz von 60kHz, oder sowas
In ASM hatte ich 1,3 Mhz
Soviel zur Effektivität

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ähm... wie hast du da getoggelt ??

der gcc nimmt normal alles als int16 an... also schön auf int8
runtercasten...dann sollte toggeln in einer schleife genau so schnell
sein... oder zumindest um faktor 10 schneller zumindest...

73 de oe6jwf

Autor: A.K. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Nicht recht nachvollziehbar. Kommt in C praktisch das gleiche raus wie
in Assembler. 6 Takte hier wie dort. Siehe Anhang.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, mit Imagecraft siehts schlechter aus, 10 Takte. Aber dessen
Compiler-Technik ist auch ziemlich vorsintflutlich.

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja

PORTB ^= 0x01;

kenn ich noch nicht. Sweit habe ich in dem C-Buch noch nicht gelesen.
Ich habs halt so gemacht

while(1)
{
PORTB = 0x55;
PORTB = 0xaa;
}

Damit hab ich zwar 8 Bit getoggelt, aber soweit ich das gelesen habe
macht das beim AVR keinen Unterschied.
Compiler war das AVR-Studio

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR Studio hat keinen C-Compiler. Jedenfalls nicht von Haus aus. Man
kann wohl welche einbinden, z.B. IAR.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
doch, das macht einen riesen unterschied.

aus :
PORTB = 0x55;
PORTB = 0xaa;
wird in asm:
out PORTB, 0x55;
out PORTB, 0xAA;
dabei macht du eine explizite zuweisung.

bei PORTB ^= 0x01;
liest du Port B zurück, und nimmst es exklusiv oder bit bit0, du
veränderst also nur das eine bit und lässt die anderen sozusagen völlig
unangetastet.

MfG
Sebastian

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Sebastian: Macht schon einen Unterschied, aber nicht hinsichtlich der
Laufzeit. Denn Compiler und Assembler(-Programmieren) haben beide das
gleiche Problem.

Diesen OUT Befehl gibt's übrigens nicht. Wodurch es sein kann, dass
der Compiler den fixeren Code erzeugt, denn grad der GNU-Compiler
pflegt recht konsequent schleifeninvarianten Code (OUT port,0x55 = LDI
tmpreg,0x55; OUT port,tmpreg - darin also der erste Befehl) aus der
Schleife raus zu befördern. Anders ein auf Übersichtlichkeit angelegter
Assembler-Programmieren, der ebendiesen "fehlenden" Befehl oft durch
einen Macro ersetzt.

Autor: Manni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
< Der zweite Code enthält nur Konstanten. Die Berechnung übernimmt der
< Compiler. Folglich braucht's auch keine Laufzeitroutine für
Division.
Na guck, das könnte es sein. Ich komme wohl auch um ein (nicht
geplantes) Vertiefen meiner Assemblerkenntnisse rum, um Schritt für
Schritt zu verfolgen, was der Compiler da so fabriziert.

Also kann der Compiler "in erster Ebene" noch rechnen, in "zweiter
Ebene" nicht mehr. Er führt also keine weitere Analyse aus, obwohl er
auch im anderen Fall schon alle Zahlen zum rechnen hätte.
Danke und Gruß
Manni

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Normalerweise rechnet er auch ,,in zweiter Ebene'', aber sicher
kannst
du dir wirklich nur sein, wenn du den generierten Assemblercode mal
ansiehst.

Autor: Fritz Ganter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist auch ein grosser Unterschied ob du mit -O0 oder mit -O2
übersetzt.

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.