Momentan vergleiche ich die Länge von empfangenen Impulsen so wie es naheliegend ist:
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
Aber geht es auch schneller?
|
Anzeige
|
Werte schnell vergleichenMomentan vergleiche ich die Länge von empfangenen Impulsen so wie es naheliegend ist:
Aber geht es auch schneller? Je mehr man vom Kontext weiß, desto besser kann man optimieren... z.B. auch was für eine Zielplattform es ist.
8-Bit AVR mit 16-Bit TCB
Na mit dieser Fülle an Informationen kann man sicherlich sagen: Schnelleren Controller nehmen hilft.
Wie definierst du "schnell"? Wie sieht der aus diesem Code erzeugte Assembler aus? Wie ist p definiert und wie t? Welchen Optimierungslevel hast du eingeschaltet?
Ist diese if-Abfrage Teil einer Schleife mit ansteigendem i? Dann könnte man sich sparen, laufend immer wieder p[i] einzulesen, wenn man zuvor schon p[i+1] eingelesen hat. Zeig mal mehr vom Code.
Was ist "es", was willst du überhaupt machen?
aber das benötigt auch 2 Vergleiche und ist damit genau so disruptiv, hoffentlich hat der Prozessor gute branch prediction. Wenn der Prozessor Multiplikation in einem Takt schafft ist
eventuell schneller. Kommt also immer auf die Hardware an. Natürlich ist der indiziere Zugriff auf p optimierbar, aber das sollte der Compiler schaffen. Er wird auch die 2 Zugriffe pro Wert in deinem Original wohl durch Register optimieren, wenn der Prozessor davon genügende hat.
Wenn da nicht noch irgendwie "zur Sicherheit, weil das ja in einer ISR verwendet wird" ein volatile davor steht. Also Fazit: mehr vom Code zeigen (am besten in einem compilierbaren "Dreizeiler") und den erzeugten Assembler anschauen.
Ist bekannt:
Es geht mir primär nur um diese eine Zeile, ob sie irgendwie umgeschrieben werden kann, so dass das Ausführen schneller abläuft, auch wenn sich dadurch die Lesbarkeit des Codes verschlechtert. Und wenn nicht, dann nicht. Dann bin ich beruhigt.
Im Zweifelsfall kannst du direkt Assembler in den Code packen. Bestimmt ist es überflüssig, sich jedes mal 4 Werte zu holen. Woher kommt t. Kann sich der ändern oder darf der vor dem Compiler auf einen festen Wert gesetzt werden?
Optimieren kann man das nur, wenn man mehr sieht.
Es gibt jede Menge möglicher Optimierungen, wenn man mehr drumherum sieht. Aber das scheint ja geheim zu sein. Könnte sein, dass Loop-Unrolling was bringt, da dann aus p[i] eine feste Adresse wird. Eventuell bringt schon das Arbeiten mit einem Pointer, der in der Schleife weiter geschoben (äh inkrementiert) wird, was. Beim Zugriff auf p[i], muss der Compiler ja den Wert von i mit der Größe eines Elements des Arrays multiplizieren.
Ach so. Na dann ist es einfach. Mach einfach vor dem && einen Zeilenumbruch. Dann läuft deine Zeile gleich doppelt so schnell. "Tä-tä, tä-tä, tä-tä!" - "Wolle mer 'n rein lasse?" Und jetzt mal ernst: kein Schwein versteht deinen Code nur vom Ansehen dieses einen Codeschnipsels. Ich vermute mal in p[] stehen irgend welche Samplewerte? Aber was soll t da im Vergleich?
Wenn das der einzige Grund für die Optimierung ist solltest du sie lassen. Optimieren nur wenn es notwendig ist In über 90% der Fälle geht Übersichtlichkeit vor einem kleinen Performancegewinn. Außer bei Cloud systeme spart man nix, wenn der Prozessor nur 5% statt 6% Auslastung hat.
Das geht nur in seltenen Einzelfällen. Die Compiler optimieren die einzelnen Schritte schon sehr gut. Nur wenn man das Gesamtbild betrachtet kann man schon mal "Synergien" finden. Also z.B. Werte über mehrere Schleifendurchläufe wieder verwenden/durchreichen, anderen Algorithmus wählen, smartere Datenstruktur nutzen etc. Bei größeren Controllern (z.B. Cortex-M4/7) geht manchmal was durch Nutzung von SIMD-Instruktionen.
Diese Dinge kriegen die Compiler tatsächlich meist schon selbst gut hin.
Bei Ultra-Low-Power Anwendungen kann das eventuell was bringen, wenn die Schleife wirklich dominant beim Energieverbrauch ist, und man vorher schon alles andere optimiert hat (Sleep Modi, CPU-Takt etc).
^ ist die xor Operation...
Lass das mal besser den Compiler machen. Der kann auf Maschinenebene optimieren. Da muss man nicht extra den ASCII-Code umsortieren, dass der kapiert, was man selber so meint, dass grade optimal wäre, sondern es reicht, ihm mitzuteilen, dass sich die verwendeten Variablen während des Programmablaufs nicht ändern können. Es kommt eben wie gesagt darauf an, woher die zu vergleichenden Variabeln kommen und ob man sie in einem lokalen Register zwischenspeichern kann. Und dann kommt es eben auch noch drauf an, ob in der {} das Pointerregister auch noch gebraucht wird und wieder neu geladen werden muss usw. usf. Evtl. ist aber schon die Abfrage Käse, wenn das unsigned TCNT-Register in den Bereich des Überlaufs kommt und man müsste gegen solche Überlaufprobleme sowieso den Code umschreiben (und dabei die richtigen Datentypen signed/unsigned nehmen):
Dann hättte man nur 1x die Rechnung p[i+1] - p[i]. Aber auch diese einfache Formelumstellung traue ich dem Optimierer inzwischen zu. Wichtiger als Geschwindigkeit ist Lesbarkeit und „es nicht zu verdaddeln“. Selbst auf kleinstem Prozessor nutze ich dafür eine Routine (nicht „inrange“ sondern between). Verdaddeln wäre: volatile, Makro-Doppelauswertung, signed/unsigned, integral promotion, unsigned-Unterlauf, Und selbst dabei fahre ich oft harakiri und fange den signed-überlauf nicht korrekt ab, bzw. überlasse das der statistischen Codeanalyse
DU verstehst es nicht. Alleine schon der Kommentar "// t: tolerance" hilft.
Du glaubst immer noch das Märchen 9
Nennt man Mathematik, verstehst du nichts von.
Wir können nicht alle so erleuchtet sein wie du. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|