Frage Effektivität C-Code

Gast #179273
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
Gast #179274
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.
Gast #179275
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
Gast #179276
ä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
Gast #179279
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
Gast #179281
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
Gast #179282
@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.
Gast #179283
< 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
Gast #179284
Normalerweise rechnet er auch ,,in zweiter Ebene'', aber sicher
kannst
du dir wirklich nur sein, wenn du den generierten Assemblercode mal
ansiehst.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 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.