Das kann aber doch nicht bedeuten, dass der Teensy dann letztendlich gar nicht double verwendet und rechnet, obwohl es so im Code steht... oder? Denn das wäre ja fatal...
Druckbare Version
Das ist als Optimierung gedacht für solche Fälle
Hier wird bei x * 2.1 zuerst das x von float nach double gewandelt, dann als double multipliziert und dann das Ergebnis wieder in float konvertiert.Code:float x = 3.5f;
float y = x * 2.1; // f vergessen
Weil aber in typischem Arduino Code float und double häufig gemischt verwendet wird, weils auf den 8-Bittern eh das selbe ist, ist beim Teensy standardmäßig der Compilerschalter -fsingle-precision-constant gesetzt, der dazu führt, dass Fliesskommakonstanten als float interpretiert werden. Das macht den Code normalerweise schneller, weil man meist eh nur mit float rechnen will.
Wenn man explizit eine double Konstante braucht, kann man ja 2.1L schreiben, das ist dann zwar long double, aber das dürfte bei den kleinen Prozessoren auch double sein.
Ich bin mir nicht sicher, wie das die anderen getesteten Boards handhaben, muss man also die Dateien in der Arduino IDE erforschen ...
Ein weiterer Unterschied sind die Compilereinstellungen zur Optimierung. Ich bin mir ziemlich sicher die Arduino IDE optimiert beim Due den Code auf Größe, nicht auf Geschwindigkeit. Beim Teensy lässt sich das im Menu der Arduino IDE einstellen ...
aaa-ha...!
was macht er dann bei sin, cos, exp, sqrt? grundsätzlich doch double, wie es richtig wäre, oder "nur" float per XXXXf Funktionen?
Arduino M0 und M3 verwenden dann double, für float muss man die XXXXf Versionen nutzen (habe ich getestet), und so würde ich es auch an sich immer erwarten, nach allem was ich jetzt weiß.
(PS, nach den Laufzeiten zu urteilen, scheint der M4 ja IMMER für double länger zu brauchen, daher dann wohl wschl doch double, wie zu erwarten, wenn auch ohne Nutzung der fpu wie es scheint...)
Wie der Name des Schalters schon andeutet, wirkt er nur auf Konstanten.
In Standard C++ sollte bei sin, cos usw. eigentlich anhand der Parameter entschieden werden, was raus kommt
https://en.cppreference.com/w/cpp/numeric/math/sin
sinf ist nur eine zusätzliche Variante um float zu erzwingen.
- - - Aktualisiert - - -
Bei double rechnet der M4 ohne Verwendung der FPU. Das bedeutet auch deren Register bleiben unbenutzt. Optimaler Code auf den M4 macht was mit int und float gemischt und nutzt so die Prozessorregister optimal aus.
bei z.B. sin(x) ist es tatsächlich so, dass M0 und M3 immer die double Version verwenden, egal ob x double oder float ist. Analog bei exp() und sqrt() etc.
Das merkt man extrem deutlich bei den Laufzeiten: in diesen Fällen braucht man bei float x sogar 20% länger als bei double x.
Nur bei sinf() mit float x etc. sind die float-tests etwa 2x so schnell wie auf double.
Sodele,
hier meine Messwerte mit der aktuellen Teensyduino 1.42 auf Arduino 1.8.5, jeweils mit den Default-Einstellungen der IDE für Taktfrequenz und Optimierung:
Code:Benchmark for Teensy 3.2 96 MHz (Overclock) Optimize: Faster
0 2819 int_Add
1 1086 int_Mult
2 45820 double_op
2 23443 float_op
3 1797 randomize
4 3656 matrx_algb
5 1523 arr_sort
6 1955 GPIO toggle
Code:Benchmark for Teensy 3.5 120 MHz Optimize: Faster
0 2255 int_Add
1 869 int_Mult
2 32253 double_op
2 2674 float_op
3 1449 randomize
4 2642 matrx_algb
5 1231 arr_sort
6 1838 GPIO toggle
Der Teensy 3.2 hat keine FPU, das sieht man deutlich im float_op Ergebnis.Code:Benchmark for Teensy 3.6 180 MHz Optimize: Faster
0 1501 int_Add
1 579 int_Mult
2 15871 double_op
2 955 float_op
3 947 randomize
4 1279 matrx_algb
5 819 arr_sort
6 1040 GPIO toggle
Die Werte für den 3.5 sind leicht anders, als oben gepostet, könnte an einer anderen Softwareversion liegen.
Der 3.6 ist das Topmodell u.a. mit viel größerem Cache, das sieht man bei einigen Ergebnissen.