Forum: Compiler & IDEs Nutzt gcc/newlib-nano die FPU von Cortex M4F bei double?


von Stefan F. (Gast)


Lesenswert?

Mikrocontroller mit Arm Cortex M4F enthalten eine FPU für float. Wenn 
ich aber stattdessen double verwende, profitiert die Performance dann 
auch von der FPU oder wird sie gar nicht benutzt? Ich compiliere mit gcc 
und verwende die newlib-nano Bibliothek, falls das eine Rolle spielt. 
Konkret geht es mir aktuell um den STM32F303CC und STM32F303RE.

: Verschoben durch Admin
von Jim M. (turboj)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wenn
> ich aber stattdessen double verwende, profitiert die Performance dann
> auch von der FPU oder wird sie gar nicht benutzt?

Weder, noch. Die Performance sinkt leicht ab.

Grund: Funktions Parameter werden (nach ABI) in der FPU übergeben - 
Laden und Speichern von Double geht nämlich, nur das eigentliche Rechnen 
nicht.

Das bedeutet aber auch das man für die eigentliche Berechnung die Daten 
wieder aus der FPU zurück in die CPU kopieren muss. Daher kommt der 
(IIRC kleine) Performance Verlust.

von Stefan F. (Gast)


Lesenswert?

Danke Jim. Jetzt bin ich allerdings genau so dumm wie vorher. Ich glaube 
ich habe meine Frage unklar formuliert. Ich versuche es noch mal:

Laufen double Berechnungen mit FPU schneller als ohne FPU?

Dass double langsamer als float wird ist mir klar. Ich hoffe dabei, dass 
die Genauigkeit nicht automatisch auf die von float herunter fällt, oder 
doch?

FPU in Mikrocontrollern ist für mich noch totales Neuland.

von m.n. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Laufen double Berechnungen mit FPU schneller als ohne FPU?

Doch nur, wenn die FPU auch double kann. Wie soll das denn auch sonst 
gehen?
Wenn Du double brauchst, dann nimm double. Die STM32 sind auch per 
Emulation recht flott.

von Stefan F. (Gast)


Lesenswert?

m.n. schrieb:
> Doch nur, wenn die FPU auch double kann. Wie soll das denn auch sonst
> gehen?

Ich weiß es nicht. Ich dachte mir, dass die double Berechnungen 
vielleicht iterativ unter Ausnutzung der FPU stattfinden könnten.

Mich interessiert allerdings nicht, was theoretisch machbar wäre, 
sondern was der Compiler bzw. die C Bibliothek daraus macht.

von 900ss (900ss)


Lesenswert?

Stefan ⛄ F. schrieb:
> sondern was der Compiler bzw. die C Bibliothek daraus macht.

Nimm ein Testprogramm und schau dir den generierten Assemblercode an.
Bin mir nicht sicher aber ich meine, dem GCC muss man bei ARM per Option 
mitteilen, dass er Code generiert, der die FPU anspricht.
Aber die Aussage bitte mit Vorsicht betrachten, du weißt Erinnerungen ;)

von m.n. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich dachte mir, dass die double Berechnungen
> vielleicht iterativ unter Ausnutzung der FPU stattfinden könnten.

Nein, die (float) FPU ist dafür unbrauchbar.
Mantisse und Exponent werden schön mit uint32_t gerechnet.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Dankeschön. Ich mache gerade erste Experimente und bin auf ein ganz 
komische Problem gestoßen:
1
int main()
2
{
3
    init_clock();
4
    init_io();
5
6
    // Initialize the timer for 1 ms intervals
7
    SysTick_Config(SystemCoreClock/1000);
8
9
    // Switch the FPU on
10
    SCB->CPACR = 0x00F00000;
11
12
    printf("Start\n");
13
    delay_ms(100);
14
15
    while (1)
16
    {
17
        // LED an
18
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
19
20
        uint32_t start=systick_count;
21
22
        float f=1.0;
23
        for (int i=0; i<10000; i++)
24
        {
25
            f=f*1.001;
26
27
            //if (f>100000.0)
28
            //{
29
            //    f=1.0;
30
            //}
31
        }
32
33
        // LED aus
34
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);
35
36
        printf("f=%f, duration=%ld ms\n",f, systick_count-start);
37
        delay_ms(500);
38
    }
39
}

Das Programm gibt schön regelmäßig aus:
> f=21916.677734, duration=22 ms

Aber wenn ich die Auskommentierten Zeilen aktiviere bricht es noch vor 
der ersten Zeile von main() mit einer Exception ab.

Ich compiliere mit -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard 
-mthumb -O1 -g

Wenn ich die Aktivierung der FPU hingegen so mache, stürzt es nicht mehr 
ab:
1
void SystemInit()
2
{
3
    // Switch the FPU on
4
    SCB->CPACR = 0x00F00000;
5
}

Ist das so in Ordnung, oder habe ich noch einen anderen Fehler gemacht?

von temp (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich compiliere mit -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
> -mthumb -O1 -g
>
> Wenn ich die Aktivierung der FPU hingegen so mache, stürzt es nicht mehr
> ab:void SystemInit()
> {
>     // Switch the FPU on
>     SCB->CPACR = 0x00F00000;
> }
>
> Ist das so in Ordnung, oder habe ich noch einen anderen Fehler gemacht?

Das sind ja auch  2 paar Schuhe. dem Compiler sagts du nur, dass du eine 
fpu hast und verwenden willst und er baut die op-codes so und bindet die 
richtige lib ein. Davon weiss die fpu aber solange nichts, bis du sie im 
Controller auch an schaltest. Und wenn nicht knallt's.
Das f=f*1.001 schmeisst der Compiler raus, wenn du das if... 
auskommentierst. Deshalb läuft es so auch. Also, alles so wie es sein 
soll.

von Johannes S. (Gast)


Lesenswert?

und f=f*1.001; ist eine Operation mit double durch das 1.001. Es wäre 
float mit f=f*1.001f;

Wenn man Code aus Arduino oder AVR Libs übernimmt, dann wird da immer 
unnötig double verwendet weil der gcc für AVR da bisher in float 
gerechnet hat.
Man kann per Holzhammer Methode alle FP Konstanten als default float 
übersetzen lassen, ist aber auch unschön.

von Kevin M. (arduinolover)


Lesenswert?

Johannes S. schrieb:
> und f=f*1.001; ist eine Operation mit double durch das 1.001. Es wäre
> float mit f=f*1.001f;

Das wollte ich gerade auch schreiben, ist das in C nicht sogar Standard?

von Stefan F. (Gast)


Lesenswert?

> Das f=f*1.001 schmeisst der Compiler raus

Ganz sicher nicht, das erkenne ich an der printf() Ausgabe und dem 
Timing.

Ich habe eher das Gefühl, dass die auskommentierten Zeilen einen Zugriff 
auf die FPU noch vor Ausführung der main() auslösen. Denn wenn ich den 
float-Kram in eine eigene funktion auslagere (und SystemInit() leer 
lasse) stürzt es nicht mehr ab:
1
void test_float()
2
{
3
    uint32_t start=systick_count;
4
    float f=1.0f;
5
    for (int i=0; i<100000; i++)
6
    {
7
        f=f*1.001f;
8
        if (f>10000.0f)
9
        {
10
            f=sqrt(f);
11
        }
12
    }
13
    printf("f=%f, duration=%ld ms\n",f, systick_count-start);
14
}
15
16
int main()
17
{
18
    init_clock();
19
    init_io();
20
21
    // Initialize the timer for 1 ms intervals
22
    SysTick_Config(SystemCoreClock/1000);
23
24
    // Switch the FPU on
25
    SCB->CPACR = 0x00F00000;
26
27
    printf("Start\n");
28
    delay_ms(100);
29
30
    while (1)
31
    {
32
        // LED an
33
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
34
35
        test_float();
36
37
        // LED aus
38
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);
39
        delay_ms(500);
40
    }
41
}

> und f=f*1.001; ist eine Operation mit double durch das 1.001.
> Es wäre float mit f=f*1.001f;

Oha. Ich habe mich schon gewundert warm float nur marginal schneller war 
als double. Da seht ihr, warum ich vor meinen Experimenten gefragt 
hatte, welche Ergebnisse zu erwarten wären. Was nützt mir eine Serie von 
Tests mit falschen Ergebnissen, wenn ich den Fehler nicht bemerke?

Jetzt komme ich auf deutlich plausiblere Messwerte:
1
F303 mit FPU
2
f=2555.784180, duration=22 ms
3
d=2540.327709, duration=299 ms
4
5
F103 ohne FPU
6
f=2555.784180, duration=210 ms
7
d=2540.327709, duration=325 ms

Das war mit der obigen test_float() Funktion und genau das Gleiche 
nochmal mit double.

Ich sehe in der FPU einen Geschwindigkeitvorteil von Faktor 10, aber nur 
bei float. Der Test bestätigt die Aussage von m.n., dass die FPU bei 
double nutzlos ist.

Der Vergleich mit dem F103 ohne FPU zeigt dass dort double nur wenig 
langsamer ist, als float.

Für mich bleibt jetzt nur noch diese Frage offen:
Stefan ⛄ F. schrieb:
> wenn ich die Auskommentierten Zeilen aktiviere bricht es noch vor
> der ersten Zeile von main() mit einer Exception ab.

von Kevin M. (arduinolover)


Lesenswert?

Stefan ⛄ F. schrieb:
> Der Vergleich mit dem F103 ohne FPU zeigt eine für mich einen
> überraschend geringen Overhead von double gegenüber float.

naja 55% mehr Rechenzeit würde ich jetzt nicht als gering bezeichnen...

Die Frage ist eh wann man double wirklich braucht, für die meisten 
Anwendungen ist float ausreichend, und wenn nicht hat man meistens eh 
komplexere Berechnungen und dann kann man entsprechend einen µC DPFPU 
benutzen.

Es gibt im übrigen Application Notes von ST zu dem Thema: AN4044

von Stefan F. (Gast)


Lesenswert?

Kevin M. schrieb:
> Es gibt im übrigen Application Notes von ST zu dem Thema: AN4044

Danke, das lese ich jetzt mal. Spannendes Thema.

von Stefan F. (Gast)


Lesenswert?

Ich glaube zu erkennen, warum mein erstes Programm schon vor der ersten 
Zeile (init_clock) abstürzte:
1
08000dd0 <main>:
2
3
    printf("d=%f, duration=%ld ms\n",d, systick_count-start);
4
}
5
6
int main()
7
{
8
 8000dd0:  e92d 4ff0   stmdb  sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
9
 8000dd4:  ed2d 8b02   vpush  {d8}
10
 8000dd8:  b083        sub  sp, #12
11
    init_clock();
12
 8000dda:  f7ff ff63   bl  8000ca4 <init_clock>
13
    init_io();
14
 8000dde:  f7ff ffb3   bl  8000d48 <init_io>
15
...

Der Knackpunkt ist hier wohl die vpush Anweisung (Push extension 
registers onto the stack). Wenn ich den if-Block auskommentiere entfällt 
diese Anweisung.

von Alex D. (daum)


Lesenswert?

Interessant, also sichert der GCC hier schon am Anfang der Funktion ein 
Float register.

Wenn man also die FPU in der Main funktion verwenden will, muss die FPU 
schon davor aktiviert sein. Wahrscheinlich am einfachsten, das direkt im 
Startup Code zu machen.

Eventuall könnte auch eine Funktion mit
1
__attribute__((constructor))
2
void initFPU(){
3
    SCB->CPACR = 0x00F00000;
4
}
Funktionieren. Die Funktion sollte der GCC vor Eintritt in die main 
schon aufrufen.

von Stefan F. (Gast)


Lesenswert?

Alex D. schrieb:
> Wenn man also die FPU in der Main funktion verwenden will, muss die FPU
> schon davor aktiviert sein. Wahrscheinlich am einfachsten, das direkt im
> Startup Code zu machen.

So habe ich mir das jetzt auch notiert. Ich mache es wie oben gezeigt in 
SystemInit().

von Johannes S. (Gast)


Lesenswert?

Auf den M0 hauen die double noch mehr rein weil der gcc da schlechter 
optimiert, da entscheidet ein ‚f‘ schon oft darüber ob der Code noch in 
den Flash passt oder nicht. Zumindest bei den kleinen mit 16 oder 32 kB.

von Stefan F. (Gast)


Lesenswert?

Die Zeile
> sqrt(f);
in meinem float-Test ist quatsch, da sie mit Double rechnet.

von Bauform B. (bauformb)


Lesenswert?

Stefan ⛄ F. schrieb:
> Die Zeile
>> sqrt(f);
>
> in meinem float-Test ist quatsch, da sie mit Double rechnet.

dagegen hilft
1
float sqrtf(float x);

von m.n. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jetzt komme ich auf deutlich plausiblere Messwerte:
> F303 mit FPU
> f=2555.784180, duration=22 ms
> d=2540.327709, duration=299 ms
> F103 ohne FPU
> f=2555.784180, duration=210 ms
> d=2540.327709, duration=325 ms

Es wäre schön, wenn Du die Laufzeit noch auf einen einzigen Durchlauf 
umrechnen würdest, sonst werden eventuell Gerüchte genährt, die 
float/double Operationen auf einem STM32 als langsam bezeichnen.
Tatsächlich sind die Laufzeiten ja im µs Bereich.

von Stefan F. (Gast)


Lesenswert?

m.n. schrieb:
> Es wäre schön, wenn Du die Laufzeit noch auf einen einzigen Durchlauf
> umrechnen würdest

Wenn ich die Wurzel heraus nehme, also nur noch Multiplikationen mache, 
komme ich beim F303 mit 72 MHz auf

* 4800 float Multiplikationen pro ms
* 330 double Multiplikationen pro ms

Oder anders gesagt:

* 15 Takte pro float Multiplikation
* 218 Takte pro double Multiplikation

(die Wiederholschleife mit einbezogen)

Mein Ziel war hier aber nicht, einen umfassenden Benchmark zu machen, 
sondern herauszufinden, ob die FPU bei double überhaupt etwas bringt. 
Durch Vergleich mit dem F103 konnte ich bestätigen, daß dem nicht so 
ist.

von Til S. (Firma: SEGGER) (til_s)


Lesenswert?

Stefan ⛄ F. schrieb:
> Durch Vergleich mit dem F103 konnte ich bestätigen, daß dem nicht so
> ist.

Was evtl. mehr bringen könnte wäre eine optimierte Float Library:

https://www.segger.com/products/development-tools/runtime-library/technology/floating-point-library/

https://wiki.segger.com/SEGGER_Floating-Point_Library

von Nop (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:

> Jetzt komme ich auf deutlich plausiblere Messwerte:

Könntest Du die Messungen nochmal mit uint32_t wiederholen? Dann 
natürlich mit einem ganzzahligen Multiplikator, etwa 314U und einem 
folgenden Rechtsshift, etwa >>=4.

Dann könnte man gucken, inwieweit sich manuelles Fixpunktgehacke noch 
lohnt.

von 900ss (900ss)


Lesenswert?

Nop schrieb:
> Dann könnte man gucken, inwieweit sich manuelles Fixpunktgehacke noch
> lohnt

Es lohnt sich mit Sicherheit, wenn keine FPU vorhanden ist.

von Dr. MCU (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> vpush

Alex D. schrieb:
> Interessant, also sichert der GCC hier schon am Anfang der
> Funktion ein
> Float register.


Interessant ist das im Grunde genommen gar nicht. Denn der Compiler 
macht genau das, was er gemäß ABI tun muss, er sichert alle 
erforderlichen Register beim Einsprung in die Funktion main().
Daher ist es offensichtlich falsch, CAPCR erst in main() zu 
konfigurieren.
Daher entweder:
1. In main kein float benutzen
oder
2. CAPCR vor der main() konfigurieren

Wenn man es 100% korrekt machen möchte, dann ist es sogar (aufgrund des 
Pipelinings des Cortex) nötig, mittels DSB und ISB den Zugriff auf CAPCR 
zu synchronisieren, da es sonst trotzdem knallen könnte...

von m.n. (Gast)


Lesenswert?

900ss D. schrieb:
> Nop schrieb:
>> Dann könnte man gucken, inwieweit sich manuelles Fixpunktgehacke noch
>> lohnt
>
> Es lohnt sich mit Sicherheit, wenn keine FPU vorhanden ist.

Das sehe ich ganz anders, es sei denn, man baut sich gerne Fehler ins 
Programm, ohne irgendeinen Vorteil zu bekommen ;-)

Til S. schrieb:
> Was evtl. mehr bringen könnte wäre eine optimierte Float Library:

Der Vergleich der benötigten Codegröße hinkt ein wenig, da angenommen 
wird, man müßte immer den ganzen trigonometrischen Kram mit dazu linken.
Die Grundrechenarten sind in der Regel sehr kompakt und - das vermute 
ich mal - bei allen Anbietern auch in Assembler geschrieben.
Ferner sollte man auch den Preis im Auge behalten. Eine STM32H7xx MPU 
muß garnicht so teuer sein(H730/H750), spart nochmals Code und rechnet 
sicherlich eine Größenordnung schneller.
Meine Meinung zu diesem Thema.

von John Doe (Gast)


Lesenswert?

m.n. schrieb:
> Ferner sollte man auch den Preis im Auge behalten. Eine STM32H7xx MPU
> muß garnicht so teuer sein(H730/H750), spart nochmals Code und rechnet
> sicherlich eine Größenordnung schneller.
> Meine Meinung zu diesem Thema.

Nur dass die STM32H730/750 nur 128KiB Flash haben im Gegensatz zu 
Stefans STM32F303RE mit 512KiB Flash.
Könnte also knapp werden bei 75% weniger Flash...

Oder man landet bei wesentlich teureren M7.

von Stefan F. (Gast)


Lesenswert?

Nop schrieb:
> Könntest Du die Messungen nochmal mit uint32_t wiederholen?

Darauf habe ich keine Lust, meine Frage ist nämlich längst beantwortet.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Dr. MCU schrieb:
> Interessant ist das im Grunde genommen gar nicht. Denn der Compiler
> macht genau das, was er gemäß ABI tun muss, er sichert alle
> erforderlichen Register beim Einsprung in die Funktion main().

Wie erklärst du dir dann, dass das Programm ohne den if-Block auf das 
Sichern der Register verzichtet?:
1
int main()
2
{
3
    init_clock();
4
    init_io();
5
6
    // Initialize the timer for 1 ms intervals
7
    SysTick_Config(SystemCoreClock/1000);
8
9
    printf("Start\n");
10
    delay_ms(100);
11
12
    while (1)
13
    {
14
        // LED an
15
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
16
17
        uint32_t start=systick_count;
18
        float f=1.0;
19
        for (int i=0; i<10000; i++)
20
        {
21
             f=f*1.001;
22
             //if (f>100000.0)
23
             //{
24
             //    f=1.0;
25
             //}
26
        }
27
        printf("f=%f, duration=%ld ms\n",f, systick_count-start);
28
29
        // LED aus
30
        WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);
31
        delay_ms(500);
32
    }
33
}
Da ist ja immer noch die Nutzung der FPU drin!

von Stefan F. (Gast)


Lesenswert?

John Doe schrieb:
> Nur dass die STM32H730/750 nur 128KiB Flash haben im Gegensatz zu
> Stefans STM32F303RE mit 512KiB Flash.

Wobei ich wohl den Tag nicht mehr erleben werde, an dem die 512kB voll 
werden.

von Stefan F. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wie erklärst du dir dann, dass das Programm ohne den if-Block auf das
> Sichern der Register verzichtet?

Ich hab's (Knöppe vor den Augen): Der Compiler hat die ganze for 
Schleife weg optimiert. Raffiniert!

von Johannes S. (Gast)


Lesenswert?

Bin bei solchen Tests auch schon reingefallen und deklariere die 
Variablen da jetzt immer volatile.

von m.n. (Gast)


Lesenswert?

John Doe schrieb:
> Nur dass die STM32H730/750 ...
>
> Oder man landet bei wesentlich teureren M7.

H730/H750 sind M7 mit "affenschnellen" 550/480 MHz ;-)

von Johannes S. (Gast)


Lesenswert?

m.n. schrieb:
>> Oder man landet bei wesentlich teureren M7.
>
> H730/H750 sind M7 mit "affenschnellen" 550/480 MHz ;-)

evtl. war es ja so gemeint das die M7 mit viel Flash auch gleich 
deutlich teurer sind, ein H743 kostet ca. 5€ mehr.

edit:
Und der H743 rechnet auch double in Hardware.

von John Doe (Gast)


Lesenswert?

Johannes S. schrieb:
> m.n. schrieb:
>>> Oder man landet bei wesentlich teureren M7.
>>
>> H730/H750 sind M7 mit "affenschnellen" 550/480 MHz ;-)
>
> evtl. war es ja so gemeint das die M7 mit viel Flash auch gleich
> deutlich teurer sind, ein H743 kostet ca. 5€ mehr.

Genauso war das gemeint. Die H730/50 sind kein passendes "Upgrade", da 
sie viel weniger Flash-Speicher haben.
M7 mit gleichviel Speicher sind halt eben deutlich teurer.

von 900ss (900ss)


Lesenswert?

m.n. schrieb:
> Das sehe ich ganz anders, es sei denn, man baut sich gerne Fehler ins
> Programm, ohne irgendeinen Vorteil zu bekommen ;-)

Ich hatte Integerrechnung im Kopf bei meiner Antwort.
Hmmmm.... ich habe Integer mit Fixpoint verwechselt. Wobei es ja oft 
notwendig ist, die Integerwerte zu skalieren, was ja eigentlich ein 
verstecktes Fixpoint ist.

von m.n. (Gast)


Lesenswert?

900ss D. schrieb:
> Wobei es ja oft
> notwendig ist, die Integerwerte zu skalieren, was ja eigentlich ein
> verstecktes Fixpoint ist.

Ja gut. Aber diese Fixpointgeschichte ist doch aus einer Zeit, als die 
CPUs noch mit 1 MHz getaktet wurden. Manche Leute meinen, man müsse es 
bis in alle Zeiten so fortsetzen und haben Angst vor float und 
Interrupts, die mehr Anweisungen haben als PUSH, POP und RETURN.
Bei den oben gezeigten Ausführungszeiten im µs-Bereich selbst für 
double-Berechnungen ist es doch nicht mehr notwendig, solche Tricks 
anzuwenden.
Lass den Compiler doch optimieren und den Controller das rechnen: man 
schreibt die Formeln so, wie man es braucht.

John Doe schrieb:
> M7 mit gleichviel Speicher sind halt eben deutlich teurer.

Und was kosten F303 mit >= 512 KB RAM?

von Stefan F. (Gast)


Lesenswert?

m.n. schrieb:
> Und was kosten F303 mit >= 512 KB RAM?

4,90€ bei 100 Stk Abnahme

von 900ss (900ss)


Lesenswert?

m.n. schrieb:
> Lass den Compiler doch optimieren und den Controller das rechnen: man
> schreibt die Formeln so, wie man es braucht.

Ich stimme dir zu aber Integerrechungen sind einfach schneller als Float 
wenn man keine FPU hat. Und darum ging es. Ob es sinnvoll ist, auf Float 
zu verzichten muss ja jeder selber entscheiden. Bei 8-Bit MCUs würde ich 
da schon eher hinsehen ;)

von HackerJ (Gast)


Lesenswert?

If you use the GCC option "-fshort-double" (Use the same size for double 
as for float) then a single precision FPU would be used for "double" 
operations.

von Nils (Gast)


Lesenswert?

Wenn man nur float nutzen möchte, dann lohnt es sich, den Code mal mit 
-Wdouble-promotion zu kompilieren.

So sieht man schön, wo man den f suffix bei Konstanten vergessen hat 
oder ausversehen double Routinen aufruft.

von Stefan F. (Gast)


Lesenswert?

HackerJ schrieb:
> If you use the GCC option "-fshort-double" (Use the same size for double
> as for float) then a single precision FPU would be used for "double"
> operations.

Ja aber dann auch nur mit der Genauigkeit von float.

von Bauform B. (bauformb)


Lesenswert?

Stefan ⛄ F. schrieb:
> HackerJ schrieb:
>> If you use the GCC option "-fshort-double" (Use the same size for double
>> as for float) then a single precision FPU would be used for "double"
>> operations.
>
> Ja aber dann auch nur mit der Genauigkeit von float.

Schön wäre es. Das Flag gibt es leider nicht mehr, jedenfalls nicht für 
Cortex-M. Vielleicht noch für einzelne Architekturen wie Mips (als 
-mshort-double?).
Beitrag "GCC Compiler Flags"

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.