Forum: Mikrocontroller und Digitale Elektronik Allgemeine Codeoptimierung in C für uC


von Sa W. (sawe)


Lesenswert?

Hallo Forum,
ich weiss jetzt nicht in welches Forum das rein sollte, da es um 
Programmieren und um uCs geht.
Ich wollte mal allgemein fragen ob jemand Tipps oder gute Seiten im Netz 
kennt, wo es darum geht, wie man Programmcode optimieren/verbessern 
kann. Ich finde dazu leider keine passenden Seiten und wenn dann geht es 
meist um JAVA.
Ich weiss zum Beispiel, dass es sinvoller ist statt "/2" zu rechnen, die 
Bitverschiebung ">>1" zu nutzen, da man hierbei Zeit spart.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Sa We schrieb:
> Ich weiss zum Beispiel, dass es sinvoller ist statt "/2" zu rechnen, die
> Bitverschiebung ">>1" zu nutzen, da man hierbei Zeit spart.

Ein moderner Compiler auch und optimiert das ...

von Martin (Gast)


Lesenswert?

Sa We schrieb:
> Ich weiss zum Beispiel, dass es sinvoller ist statt "/2" zu rechnen, die
> Bitverschiebung ">>1" zu nutzen, da man hierbei Zeit spart.

Und nichtmal das stimmt für alle Plattformen.

Das Beste ist, plattform- und compilerunabhängigen Code zu schreiben. 
Die Optimierung kann man dann ruhig dem Compiler überlassen. Nur wenn es 
unumgänglich ist kann/muss man von dieser Regel abweichen. Beispiele 
sind Startup-Code, Hardware-/Registerzugriffe oder extrem zeitkritische 
Sachen - wobei letzteres ein Streitpunkt ist, da oft ein Denkfehler 
und/oder schlechte SW-Archtitektur zugrunde liegt, wenn man das machen 
muss...

von Mr.T (Gast)


Lesenswert?

Brain Mk.1 ist ein guter Optimierer... zumindest bei einigen Menschen ;)

von Karl H. (kbuchegg)


Lesenswert?

Sa We schrieb:

> Ich weiss zum Beispiel, dass es sinvoller ist statt "/2" zu rechnen, die
> Bitverschiebung ">>1" zu nutzen, da man hierbei Zeit spart.

Und du denkst echt, Compilerbauer hätten in 50 Jahren nicht gelernt, wie 
man sowas einem Compiler beibringen kann?

PS: Im übrigen stimmt das gar nicht.
Rechne mal   -3 / 2  und dann vergleichst du mit dem Ergebnis von -3 >> 
1
:-)
Compiler wissen nämlich auch das: unter welchen Umständen ist eine 
derartige Optimierung überhaupt möglich.

von Sa W. (sawe)


Lesenswert?

Karl Heinz Buchegger schrieb:
> wie man sowas einem Compiler beibringen kann?

Das war ja nur ein Beispiel, wovon ich es weiss.
Das die Compiler das selber auch tun war mir schon klar :)

Ich dachte eben, dass es so bestimmte Dinge gibt, die man eben allgemein 
von vornherein beachten sollte, die man eventuelle aus eigener Erfahrung 
weiss.

von Peter D. (peda)


Lesenswert?

Die beste Anlaufstelle ist immer die Webseite des konkreten Compilers 
(z.B. Keil C51) oder des konkreten MC-Herstellers (z.B. Atmel AVR).

Da findet man sowohl spezifische als auch allgemeine Optimierungstips.

von Karl H. (kbuchegg)


Lesenswert?

Sa We schrieb:

> Ich dachte eben, dass es so bestimmte Dinge gibt, die man eben allgemein
> von vornherein beachten sollte, die man eventuelle aus eigener Erfahrung
> weiss.

Schreib den Code so, dass er gut lesbar, wartbar und übersichtlich ist.
Verwende den kleinsten Datentyp der angemessen ist
Verwende einen angemessenen Algorithmus
Kenne dein Werkzeug - die Programmiersprache


Und um den Kleinscheiss: lass den den Compiler erledigen.

Wenn dann dein Programm nachweislich zu langsam ist, dann fange mit 
Optimierungen an, wobei du zuerst auf der hohen algorithmischen Ebene 
nach Verbesserungen suchst. Wenn da wirklich alles ausgereizt ist, dann 
profile deinen Code, um die Stellen zu finden, an denen das Bottleneck 
sitzt. Sieh dir dort den Assemblerteil an und versuch ein wenig 
nachzuvollziehen, wie sie mit diesem konkreten Compiler entstanden sind. 
Überleg, welches C-Konstrukt wohl den Compiler von anderer Optimierung 
abgehalten hat. Versuch dann, den C-Code so zu verändern, dass sich dem 
Compiler andere Optimierungen ermöglichen.

Aber in der überwiegenden Mehrzahl der Fälle ist ein sauber und nicht 
blödsinnig pessimiertes C-Programm aus der Box heraus schnell genug. 
Optimiere nicht zusätzlich, wenn du nicht musst. Ist ein Programm 
schnell genug, dann reicht das. Dazu gehört auch, dass man die zu 
erzielenden Grenze "wann ist es schnell genug" kennt.

Optimierungen beginnen beim Algorithmus. Auch der am besten auf 
Assembler-Ebene optimierte Bubble-Sort wird selbst gegen den lausigsten 
Quick-Sort bei hinreichenden Datenmengen immer das nachsehen haben.

Bis auf ganz wenige Ausnahmen: Speed holt man sich nicht dadurch, dass 
man 2 Befehle auf Assembler-Ebene durch eine trickreiche C-Schreibweise 
einspart. Und wenn du soweit bist, dass du diese 2 Takte tatsächlich 
brauchst, dann hast du auch genug gelernt um zu wissen wie und warum man 
welche Änderung macht und wie sich die im Assemblercode auswirkt.

von Kaj (Gast)


Lesenswert?

Kommt drauf an, wass du optimieren willst.
Wenn du z.B. auf einem AVR unterwegs bist, dann ist es für die 
ausführungszeit besser wenn du:
1
for(unsigned char i=0; i<255; i++)
2
{
3
  for(unsigned char j=0; j<255; j++)
4
  {
5
    //tu was
6
  }
7
}

als:
1
for(unsigned int i=0; i<64516; i++)
2
{
3
  //tu was
4
}
schreibst. Die zwei for-Schleifen sind einfach schneller.

Hängt aber eben davon ab, was du wo und wie machen willst.

von spess53 (Gast)


Lesenswert?


von Falk B. (falk)


Lesenswert?

AVR-GCC-Codeoptimierung

Die allgemeinen Sachen gelten nicht nur für AVR GCC.

von Sa W. (sawe)


Lesenswert?

Vielen Dank euch.
Da waren doch schon ein paar sehr gute Dinge bei.
Werde mir die

spess53 schrieb:
> http://www.atmel.com/Images/doc8453.pdf
>
> http://www.atmel.com/Images/AVR4027.zip

und

Falk Brunner schrieb:
> AVR-GCC-Codeoptimierung

mal durchlesen.

von amateur (Gast)


Lesenswert?

@Sa We

Schau mal unter dem Stichwort: lint nach. Ob das Teil beim Optimieren, 
vom "C"-Code, der nahe an der Hardware geschrieben wurde hilft, weiß ich 
nicht.

von Erich (Gast)


Lesenswert?

Für den (automotive) embedded Bereich gibt es die MISRA Regeln für "C".
Wenn man die befolgt, sind automatisch schon etliche 
ortimierungsfördernden Dinge erledigt.
Den Rest bzw. die Optimierung selbst macht der Compiler.
Bei hoher (guter) Optimierungseinstellung wird beispielsweise bei /2 und 
>>1 identischer .hex bzw. Binärcode rauskommen.
Wichtig ist: Größe der Variablen beachten, implizite cast vermeiden 
(also cast selbst hinschreiben wo erfoderlich, schon zur Klarheit) und 
float ganz meiden, ausser in #define oder Berechnungen wo resultierend 
eine Konstante als Integer rauskommt.

Klaus

von Bernhard S. (b_spitzer)


Lesenswert?

Erich schrieb:
> Bei hoher (guter) Optimierungseinstellung wird beispielsweise bei /2 und
> >>1 identischer .hex bzw. Binärcode rauskommen.
Gerade hier muss man aber aufpassen. Bei Rechts-Shift arbeitet ein 
C-Compiler vorzeichenkorrekt. Ein vorzeichenloser Datentyp erhält im 
obersten Bit beim rechtsschieben immer eine 0, ein vorzeichenbehafteter 
Datentyp bekommt das vorletzte Bit.
Das Beispiel von Karl Heinz weist in die richtige Richtung:
-3/2 ergibt -1, -3>>1 ergibt -2.

Kleines Dummy-Programm mit Debug-Ausgabe dazu:
1
    unsigned char a=-3;      // impliziter Type-Cast
2
    signed char b=-3;
3
    Ergebnis = a;            // 0xFD = Zweierkomplement von -3, 
4
    while(1)                 // wird jetzt aber als +253 interpretiert
5
    {
6
        if(P3_2)
7
            Ergebnis = a/2;  // 0x7E
8
        else
9
            Ergebnis = a>>1; // 0x7E
10
        if(P3_3)
11
            Ergebnis = b/2;  // 0xFF
12
        else
13
            Ergebnis = b>>1; // 0xFE
14
    }

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
Noch kein Account? Hier anmelden.