sinf() langsam?

OP #7216688
Lesenswert?

Guten Morgen,

ich nutze den gut abgehangenen ARM-GCC 5.4.1, aber die vorliegende 
Problematik dürfte sich nicht geändert haben. MCU ist ein Cortex M4F 
(STM32F446RE) und die float-Erweiterungen werden genutzt.

Meine Beobachtung: Für kleine Eingangswerte ist die Funktion sinf() 
ziemlich schnell (grob 250 Takte), für große ( > 10*2*pi) wird sie aber 
ziemlich schnell langsam (> 2000 Takte).

Wo kann ich ich mir den Quelltext der builtin-Funktionen anschauen, um 
der Sache auf die Schliche zu kommen?

Gibt es irgendwo Informationen, bei welchen eingebauten Funktionen ich 
ebenfalls unerwartet massiv unterschiedliche Laufzeiten in Abhängigkeit 
der Eingabewerte erwarten muss? (Bei einem memcpy() oder printf() ist es 
nicht unerwartet, bei einem sinf() schon.)
OP #7216713
Lesenswert?

Μαtthias W. schrieb:
> Das hier
> 
https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libm/mathfp/sf_sine.c;h=8dd34d9a1dac27ecd3e3fce50264977edde88640;hb=refs/heads/master
> ist aber mit hoher Wahrscheinlichkeit das was du suchst.

Besten Dank! Sogar mit zitiertem Lesestoff.

Das muss ich mich heute abend mal in Ruhe zu Gemüte führen. Auf Anhieb 
finde ich nämlich nichts, was abhängig vom Funktionsparameter die 
Laufzeit ernsthaft beeinflussen könnte.
Gast #7217004
Lesenswert?

Walter T. schrieb:
> Auf Anhieb
> finde ich nämlich nichts, was abhängig vom Funktionsparameter die
> Laufzeit ernsthaft beeinflussen könnte.

Rein technisch besteht der Knackpunkt darin, daß man für 
Winkelfunktionen nur Winkel in einer einzigen Vollperiode braucht und da 
zum Berechnen auch nur im ersten Quadranten.

Folglich müssen ganze Perioden zuvor abgetrennt werden und dann alles 
auf eben diesen ersten Quadranten gefaltet werden - unter Vermerk, in 
welchem Quadranten der Winkel eigentlich lag.

So ein Vorgeplänkel ist für allgemeine Winkelfunktionen immer nötig. Und 
darin liegt auch der Unterschied für verschiedene Input-Werte.

W.S.
Gast #7217025
Lesenswert?

W.S. schrieb:
> Folglich müssen ganze Perioden zuvor abgetrennt werden und dann alles
> auf eben diesen ersten Quadranten gefaltet werden - unter Vermerk, in
> welchem Quadranten der Winkel eigentlich lag.

Genau, und man sollte es mit der Größe der Argumente - gerade bei der 
kümmerlichen Genauigkeit von float - nicht übertreiben, sonst kann man 
auch einfach würfeln ... So findet man im steinalten MC68881 Manual:

"If the source operand is not in the range of [-2*\pi ... 2*\pi], then 
the argument is reduced to within that range before ... is calculated. 
However, large arguments may lose accuracy during reduction, and very 
large arguments (greater than approximately 10^20) loose ALL 
accuracy." Und das war bei Register-Argumenten, also 80-Bit FP-Format. 
Wann das bei float zuschlägt, kann man sich dann auch überlegen ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren