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.
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 ...
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...
Brain Mk.1 ist ein guter Optimierer... zumindest bei einigen Menschen ;)
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.
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.
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.
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.
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.
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.
@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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.