Hallo!
Gibt es eine Möglichkeit den gcc dazu zu bringen einzelne Funktion mit
Os und andere mit O3 zu kompilieren?
Beispiel wäre z.B. ein Programm mit zeitkritischen Interrupts: Den
Interrupts spendiert man zugunsten der Geschwindigkeit mehr Flash, bei
dem eher unkritischen Hauptprogramm versucht man Platz zu sparen.
Grüße
Robert
Oh, das ist ja schick. Gibt's aber auch noch nicht so lange, oder?
Ansonsten kann man natürlich auch einfach die Funktionen, die andere
optimierungs-Einstellungen brauchen, in eine eigene .c-Datei (oder
mehrere) stecken und diese mit den speziellen Einstellungen übersetzen.
Hm, schade, so gehts nicht:
__attribute__((optimize("O3"))) ISR(TIMER1_COMPA_vect)
{
...
}
führt zu
warning: 'optimize' attribute directive ignored
Ein testweises "const" (was quatsch ist) läuft durch. Die Schreibweise
O3 -O3 3 etc. habe ich schon versucht.
Grüße
Robert
Könnte sein, dass dies erst ab 4.4 geht. Bei den Pragmas steht das so
explizit drin.
Allerdings kann es auch sein, dass der Makro ISR() mitmischt. Muss man
genauer ansehen, was dabei hinten aus dem Präprozessor rauskommt. Ggf.
ist auch
function-declaration __attribute___(...) { ... }
also Attribute dahinter der richtige Weg.
Robert B. schrieb:
> Beispiel wäre z.B. ein Programm mit zeitkritischen Interrupts: Den>> Interrupts spendiert man zugunsten der Geschwindigkeit mehr Flash,
Schlechtes Beispiel. ISR's, besonders zeitkritische, sind (bzw. sollten)
so kurz sein, daß da die verschiedenen Optimierungsstufen gar keinen
Unterschied machen.
Und im Falle des avr-gcc ist -O3 sowieso zweckfrei. Ernsthaft schneller
als mit -Os wird es damit nicht. Als Risk-Prozessor mit einem (oder
zwei) Zyklen pro Befehl gilt beim AVR kurz = schnell.
Oliver
Rolf Magnus schrieb:
> Scheint so, denn unter> http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Functi...> wird dieses Attribut nicht erwähnt.
Ja, hab's gerade ausprobiert: 4.4.2 unterstützt das Attribut, 4.3.4 und
4.2.4 nicht.
Oliver schrieb:
> Robert B. schrieb:>> Beispiel wäre z.B. ein Programm mit zeitkritischen Interrupts: Den>>>> Interrupts spendiert man zugunsten der Geschwindigkeit mehr Flash,>> Schlechtes Beispiel. ISR's, besonders zeitkritische, sind (bzw. sollten)> so kurz sein, daß da die verschiedenen Optimierungsstufen gar keinen> Unterschied machen.>> Und im Falle des avr-gcc ist -O3 sowieso zweckfrei. Ernsthaft schneller> als mit -Os wird es damit nicht. Als Risk-Prozessor mit einem (oder> zwei) Zyklen pro Befehl gilt beim AVR kurz = schnell.>> Oliver
-Os
1
if (tmp_vel > 0) {
2
722: 14 16 cp r1, r20
3
724: 1c f4 brge .+6 ; 0x72c <__vector_11+0xa2>
4
act_pos_buf++;
5
726: cb 01 movw r24, r22
6
728: 01 96 adiw r24, 0x01 ; 1
7
72a: 02 c0 rjmp .+4 ; 0x730 <__vector_11+0xa6>
8
} else {
9
act_pos_buf--;
10
72c: cb 01 movw r24, r22
11
72e: 01 97 sbiw r24, 0x01 ; 1
12
}
-O3
1
if (tmp_vel > 0) {
2
7b2: 14 16 cp r1, r20
3
7b4: 0c f0 brlt .+2 ; 0x7b8 <__vector_11+0xae>
4
7b6: 46 c0 rjmp .+140 ; 0x844 <__vector_11+0x13a>
5
act_pos_buf++;
6
7b8: cb 01 movw r24, r22
7
7ba: 01 96 adiw r24, 0x01 ; 1
8
} else {
9
act_pos_buf--;
10
}
11
...
12
if (tmp_vel > 0) {
13
act_pos_buf++;
14
} else {
15
act_pos_buf--;
16
844: cb 01 movw r24, r22
17
846: 01 97 sbiw r24, 0x01 ; 1
18
848: b9 cf rjmp .-142 ; 0x7bc <__vector_11+0xb2>
19
}
das mit avr-gcc 4.3.3
Keine Ahnung warum der gcc bei -O3 einen Code dermaßen zerrupft - super
unschön. Zumal mit schlechter lesbarer Nachhilfe die Optimierung viel
besser ist:
-O3 / Os
Robert B. schrieb:
> unverständlich warum er nicht erzeugt:> [...]> ...sollte ja equivalent sein...
Weil ein Compiler kein Werkzeug ist, das in jedem speziellen Einzelfall
einen garantiert nicht weiter optimierbaren Code erzeugt. Aber es ist
durchaus möglich, ihm das in diesem Fall beizubringen, der Quellcode ist
öffentlich.
A. K. schrieb:
> Robert B. schrieb:>>> unverständlich warum er nicht erzeugt:>> [...]>> ...sollte ja equivalent sein...>> Weil ein Compiler kein Werkzeug ist, das in jedem speziellen Einzelfall> einen garantiert nicht weiter optimierbaren Code erzeugt. Aber es ist> durchaus möglich, ihm das in diesem Fall beizubringen, der Quellcode ist> öffentlich.
Warum mit leicht genervten Unterton? Ist doch völlig fehl am Platz...
Ich stelle hier eine Frage rein und freue mich wenn jetzt jemand sagt
"hilf dem Compiler so und so". Dass der Compiler nicht jeden Spezialfall
erkennen kann (und da habe ich auch schon ein paar inline-hacks aus
gutem Grund gemacht) ist völlig klar - bei diesem Szenario wundert es
mich halt.
Spätestens bei dem "helfenden" C-Code sollte der Compiler doch erkennen,
dass er nachdem er den Drecrement gemacht hat abhängig vom Vorzeichen
nur einen einzigen Befehl überspringen oder ausführen muss.
Robert B. schrieb:
> Warum mit leicht genervten Unterton? Ist doch völlig fehl am Platz...
Wie es in den Wald reinruft, so schallt es zurück. Vielleicht habe ich
deinen Anspruch "unverständlich warum er nicht erzeugt:" auch etwas
misverstanden.
Jedenfalls ist der Code, den du als optimalen Ersatz gebastelt hat,
nicht unbedingt typisch für den Output eines Compilers. Es sei denn
jemand hat ihn speziell dafür optimiert (sowas kommt gelegentlich bei
auf spezielle Sequenzen bekannter Benchmarks optimierenden Compilern
vor).
> Spätestens bei dem "helfenden" C-Code sollte der Compiler doch erkennen,> dass er nachdem er den Drecrement gemacht hat abhängig vom Vorzeichen> nur einen einzigen Befehl überspringen oder ausführen muss.
Deine Variante setzt voraus, dass beide Zweige vom "if" in Beziehung
gesetzt werden und der Compiler erkennt, dass er die darin enthaltene
Arithmetik aufeinander aufbauen kann, statt sie alternativ auszuführen.
Sowas lässt sich in den Compiler einbauen, aber offenbar hat das eben
niemand getan.
Was ich hingegen auf Architekturen mit Predication (z.B. ARM) schon
gesehen habe ist sinngemäss sowas wie
cmp tmp_vel, #0
if.gt add act_pos_buf, #1
if.le sub act_pos_buf, #1
und bei bei solchen mit bedingtem Move (x86 >= 686) findet man sowas wie
add temp, act_pos_buf, #1
sub act_pos_buf, #1
cmp tmp_vel, #0
if.gt move act_pos_buf, temp
um den oft problematischen Sprung zu vermeiden. Das sind eher generische
Optimierungen. Das letztere allerdings liesse sich auch mit AVRs machen,
es wird dort aber weder kürzer noch schneller.