Vom PIC-Compiler von MicroChip erzeugte Fremdschleife

7

Wir verwenden die Lite-Version des MicroChip PIC-Compilers. Vielleicht ist das der Grund, aber diese einfache Ein-Bit-Verschiebung erzeugt eine Schleife, in der keine erforderlich ist. Da die Verschiebungszahl 1 (eine Konstante) ist, würde ich erwarten, dass der Compiler keine Schleife erstellt - eine elementare Optimierung.

Gibt es einen Compiler-Optimierungsschalter, der die Schleife verringern würde? Hier ist der Code für die Schicht:

    long foo;   // a 32-bit value

// Shift foo one bit. 
// A one-iteration loop is created!

    foo >>= 1;

Und hier ist der vom Compiler generierte Code. Wie Sie sehen können, wird die Verschiebung mit einer Schleife mit einer Iteration umschlossen.

  07F6    3001     MOVLW 0x1
  07F7    00F2     MOVWF 0x72
  07F8    37F6     ASRF 0x76, F
  07F9    0CF5     RRF 0x75, F
  07FA    0CF4     RRF 0x74, F
  07FB    0CF3     RRF 0x73, F
  07FC    0BF2     DECFSZ 0x72, F

BEARBEITEN

Compiler-Version: HI-TECH C-Compiler für PIC10 / 12/16-MCUs (Lite-Modus) V9.81

IJ Kennedy
quelle
3
Kannst du genau welchen Compiler posten? Micochip bietet jetzt neben Compilern der C-Serie auch Compiler der XC-Serie an. Seit Microchip Hi-Tech übernommen hat, nennen einige Leute Hi-Tech-Compiler auch Microchip-Compiler.
AndrejaKo
4
Verwenden Sie keinen Compiler, wenn Sie sich mit einzelnen Anweisungen quälen möchten.
Olin Lathrop
2
@OlinLathrop - Unsinn. Ich würde ein ganzes Kapitel darüber schreiben, wie falsch diese Aussage ist. Dies ist kein Fall von Qual über einzelne Anweisungen, dies ist ein Hinweis darauf, dass der Compiler sehr schlechten Leistungscode generiert.
Raketenmagnet
4
@Rocket: Ihnen fehlt der Punkt, dass der Compiler das tun wird, was er tut. Sie sind die Sorge um individuelle Anweisungen , da man sie sah und beschlossen , sie ineffizient waren. Entweder verwenden Sie eine Hochsprache oder nicht. Wenn ja, beschweren Sie sich nicht darüber, was unter der Haube vor sich geht. Wenn Sie es besser wollen, zahlen Sie für das Optimierungsprogramm, besorgen Sie sich einen besseren Compiler (falls vorhanden) oder schreiben Sie in Assembler.
Olin Lathrop
2
@OlinLathrop - Ich wünschte, ich hätte Raum, um näher darauf einzugehen, warum Sie hier falsch liegen.
Raketenmagnet

Antworten:

2

Möglicherweise liegt dies daran, dass die Lite-Version nicht optimiert wurde.
Du könntest es versuchen,

foo /= 2;

und sehen, ob es hilft.

Bruno Ferreira
quelle
foo / = 2 generiert 28 Verschiebungsanweisungen plus einen Aufruf an eine lange 32-Bit-Teilungsroutine.
IJ Kennedy
Haben Sie versucht, den Code mit XC8 zu kompilieren?
Bruno Ferreira
1

Ich habe verschiedene Optimierungsoptionen ausprobiert, aber nichts hat den Compiler dazu gebracht, vernünftigen Code zu produzieren. Ähnliche Erfahrungen habe ich auch mit dem C18-Compiler gemacht. Ein Teil des Codes, den es generiert, ist erstaunlich dumm, und am Ende habe ich verschiedene Arten von Makros und Tricks verwendet. Am Ende war ich in der Lage, Code so gut wie handoptimierten Assembler zu generieren und dabei ziemlich lesbar zu bleiben.

Dieses nicht sehr schöne Makro generiert den richtigen Assembler für eine lange Rechtsverschiebung.

long foo;

#define R_SHIFT_LONG(x)     asm("asrf    _" #x "+3, f"); \
                            asm("rrf     _" #x "+2, f"); \
                            asm("rrf     _" #x "+1, f"); \
                            asm("rrf     _" #x "+0, f");

void main(void)
{
    foo=1234;

    R_SHIFT_LONG(foo);
}
Raketenmagnet
quelle
Ich weiß nicht, für welche Maschine dieses Makro Ihrer Meinung nach gedacht ist, aber es gibt keinen 8-Bit-PIC, der sowohl einen ASRF- als auch einen RRCF-Befehl enthält.
Olin Lathrop
Wie seltsam. Der Compiler hat keinen Fehler oder keine Warnung generiert, sondern nur die rrcf stillschweigend in rrf konvertiert.
Raketenmagnet
Ah, Sie nehmen also anscheinend einen der erweiterten 14-Bit-Kerne an. Wenn ihr Anweisungen guckt, müsst ihr wirklich sagen, für welchen PIC der Code ist.
Olin Lathrop
@OlinLathrop - Nun, ich gehe von demselben Befehlssatz aus, den das OP verwendet.
Raketenmagnet
-1

Jetzt, wo ich die Gelegenheit hatte, mir Ihren Code anzusehen, ist das wirklich nicht so unvernünftig. Je nach PIC-Modell könnte dies in 4 oder 5 Anweisungen erfolgen, jedoch nur im speziellen Fall einer Verschiebung um ein Bit . Es erscheint ziemlich vernünftig, dass der Compiler als erstes Code für den allgemeinen Fall schreibt, in dem die Verschiebung für N Bits gilt. Es würde mich wundern, wenn eine Verschiebung um ein Bit nicht als Sonderfall mit aktivierten Optimierungen erkannt würde, aber wie ist das nicht genau das, was Sie ohne Optimierung erwarten?

Wenn Sie sich jedoch für diesen Detaillierungsgrad interessieren, sollten Sie in Assembler schreiben. Durch die Verwendung eines Compilers haben Sie die detaillierte Befehlsgenerierung entfernt. Außerdem ist es grob unfair, einen Compiler mit deaktivierten Optimierungen zu bewerten.

Olin Lathrop
quelle
2
Der Compiler tut dies anscheinend sogar, wenn die Optimierungen aktiviert und auf 9 gesetzt sind.
Rocketmagnet