DEVUAN!
30.06.2017
17.06.2017
Garten - Topfbewässerung Hinten
Der Rasen hinten dürstet nach Wasser. Es gibt da so eine Stelle die ständig austrocknet. Wahrscheinlich scheint hier einfach mehr Sonne drauf, und der Baum will auch seinen Anteil.
Durch mehr Gießen bekomme ich die Stelle jedenfalls nicht in Griff. Auch hier muss eine Tropfleitung hin!
Garten - Topfbewässerung
Mein Garten brauch wenig Wasser. Und da ist das Problem. Einmal Abends mit dem Schlauch drüber ist einfach zu viel Wasser in zu kurzer Zeit. Vielmehr brauch die Erde mäßig Wasser über einen langen Zeitraum. Aber ich bin nun mal viel zu ungeduldig um 10-20min mit einem feinen Sprühstrahl abends im Garten zu sehen. Einmal vorne und noch einmal hinten.
Wenn ich mehr Power auf den Schlauch lege, fließt das Wasser einfach nur in die nächste Ritze und weg ist es. Eine Tropf-Bewässerung muss her!
Beim Toom Baumarkt hab ich sogar gleich etwas gefunden. Ein Starterset für 15Eur. Mit dabei ist ein 15m langer Tropf-Schlauch und passender Anschluss. Einmal ausprobiert und ich war sofort begeistert! Die Erde wird weich und feucht. Selbst die Sahara-Stellen, welche absoluten Wüstensand darstellten, sind jetzt mit Wasser gesättigt. Da kann der Rasen gerade zu keimen.
Also ich bin wirklich begeistert. Im Umkreis von 15cm um eine Topfstelle bildete sich feuchte Erde. Wirklich perfekt. Der Wasserverbrauch ist auch sehr gering. Es wird 1.5l/h angegeben. Aber wenn ich den Wasserhahn noch etwas weiter zu drehe, ist es noch weniger. Und ich kann bedenkenlos die Sache über Nach anlassen. Wenn die Leitungen auf der Oberfläche nur nicht so hässlich wären... Aber man kann sie ja vergraben! :D
Dummerweise wächst kein Gras mehr da, wo ich gewütet habe. Muss ich wohl neues säen. Aber das macht nichts. Zwei von Sechs Tropfleitungen sind schon verlegt. Die Erde wird wunderbar gesättigt und das Gemüse kann wachsen.
Ich habe keine Kosten gescheut und 45m Tropfleitung und 20m Gartenschlauch gekauft. Wenn alles sauber verbaut ist, kann alles wunderbar wachsen. Und ich muss nicht mehr um Mitternacht da stehen und gießen.
15.06.2017
Garten - Kleines Gewitter - Überschwemmung
Ein kleines Sommergewitter, und schon steht im Garten das Wasser 3-4cm hoch. Der Gulli am Wasserstein hat seine Aufgabe einfach nicht verstanden. Er soll das Wasser weg schlucken und nicht ausspucken. Denn das hat er fleißig gemacht. Aber auch an trockenen heißen Tagen ist diese Quelle ergiebig. Ich nehme an, es gibt eine unterirdische Verbindung zu den Duschen und Badewannen im Haus. Also quasi Trinkwasserqualität.
So ein Sommergewitter reinigt nicht nur die Luft, sondern auch die Dachrinnen. Eine, von der Terrasse, konnte ich gut beobachten. Bis zum Überquellen voll mit Wasser. Jeder Laubklumpen wird einfach hinfort gespült... rein in den Abfluss. Leider habe ich hiervon kein Bild gemacht.
Das überschüssige Wasser fällt prasselnd hinunter auf den Boden, wo es nicht hingehört, und verursacht weitere tiefe Pfützen.
Doch das Wasser sucht sich immer den Weg der bergab geht. So landet es nach kurzen Aufenthalt am Gartentor,
durch eine wohl extra für diese Zwecke angelegte Röhre in dem nächsten Gulli. Der, aus irgendeinem Grund, total wasserfrei ist
Auch im Vorgarten hat der Regenguss seine Spuren hinterlassen. Er sammelt sich gerne in Senken, die immer da sind, wo man selbst gerne ist. Und so standen die Stühle und der Tisch auch ein wenig im Wasser.
Aber nach ein paar Minuten ist alles wieder weg, und es bleibt die klare Luft.
FORTRAN: parameter variables in module evaluated at compile or runtime?
Suggest you habe a fortran module with a collection of mathematical constant like PI.
module constant_m
real, parameter :: PI = 3.1314_8
end module
Now you use this module in a function which calculate the circumcenter of a circle with given radius.
function U(r)
use constant_m
implicit none
real, intent(in) :: r
real :: U
U = 2*PI*r
end function
Will the expression 2*PI be evaluated a compile or runtime?
Lets check the generated assember code!
...
And you'll see only crap.
Let's start with an simpler example. Replace every real to integer. Truncate PI to 3, thats fair enough. And remove the "2*" expression. Somewhere in the assembler code are there must be the expression y=3*x.
Here it is:
gfortran --save-temps -O1 -c constants.F90 circle.F90
movl 4(%esp), %eax % Store the adress of r from stack pointer into eax
movl (%eax), %eax % Dereference adress and store value from r into eax
leal (%eax,%eax,2), %eax % eax = eax + 2*eax
The last line is the one. The compiler optimize the multiplicaton with 3 to an assembler instrctuin which performs a multiplication with 2 and an addition.
What we not see is a constant "3" in assember code. Or a assembler register filled with "3".
Lets add the "2*" and see whats happens.
movl 4(%esp), %eax
movl (%eax), %eax
leal (%eax,%eax,2), %eax
addl %eax, %eax
Only the last line is new. The compiler decide that x+x is more performance than 2*x. Cute.
Okay lets have some fun. We force the compiler to evaluate (2*PI) first. (2*PI)*r
And the resulting assembler code is the same HAHA.
Okay back to topic. We see that integer, parameter variables in modules are evaluated at compile time. Lets switch back to real.
Now the assembler code looks a litte bit more complicated:
flds .LC0@GOTOFF(%eax) % Load constant into floading point register
movl 4(%esp), %eax % Store value from r into eax
fmuls (%eax) % Multiply the constant with r and put the result back in eax
.LC0:
.long 1086918230 % The constand 2*PI
Now you can see a constant in assember as a 4byte iteger. Its only one constant, so I guess its 2*PI here.
This constant is loaded into a floting point register. The value from r is loaded into a second register. Then both get multiplyed. Thats all. Only a single multiplaction.
PARAMETER VARIABLES IN MODULE ARE EVALUATED AT COMPILE TIME! :D
05.06.2017
C++ Guns - GNU GCC -ffast-math und was es macht
Was macht -ffast-math eigentlich und was bringt es für Vorteile?
Aus der Dokumentation:
This option is not turned on by any -O option besides -Ofast since it can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications.
-ffast-math
Sets the options -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans, -fcx-limited-range and -fexcess-precision=fast.This option causes the preprocessor macro __FAST_MATH__ to be defined.
-fno-math-errno
Do not set errno after calling math functions that are executed with a single instruction, e.g., sqrt. A program that relies on IEEE exceptions for math error handling may want to use this flag for speed while maintaining IEEE arithmetic compatibility.The default is -fmath-errno.
-funsafe-math-optimizations
Allow optimizations for floating-point arithmetic that (a) assume that arguments and results are valid and (b) may violate IEEE or ANSI standards. When used at link time, it may include libraries or startup files that change the default FPU control word or other similar optimizations.
Enables -fno-signed-zeros, -fno-trapping-math, -fassociative-math and -freciprocal-math.
-fno-signed-zeros
Allow optimizations for floating-point arithmetic that ignore the signedness of zero. IEEE arithmetic specifies the behavior of distinct +0.0 and -0.0 values, which then prohibits simplification of expressions such as x+0.0 or 0.0*x (even with -ffinite-math-only). This option implies that the sign of a zero result isn’t significant.
-fno-trapping-math
Compile code assuming that floating-point operations cannot generate user-visible traps. These traps include division by zero, overflow, underflow, inexact result and invalid operation. This option requires that -fno-signaling-nans be in effect. Setting this option may allow faster code if one relies on “non-stop” IEEE arithmetic, for example.
-fassociative-math
Allow re-association of operands in series of floating-point operations. This violates the ISO C and C++ language standard by possibly changing computation result.
NOTE: re-ordering may change the sign of zero as well as ignore NaNs and inhibit or create underflow or overflow (and thus cannot be used on code that relies on rounding behavior like (x + 2**52) - 2**52. May also reorder floating-point comparisons and thus may not be used when ordered comparisons are required. This option requires that both -fno-signed-zeros and -fno-trapping-math be in effect. Moreover, it doesn’t make much sense with -frounding-math.
-freciprocal-math
Allow the reciprocal of a value to be used instead of dividing by the value if this enables optimizations. For example x / y can be replaced with x * (1/y), which is useful if (1/y) is subject to common subexpression elimination. Note that this loses precision and increases the number of flops operating on the value.
-ffinite-math-only
Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs.
-frounding-math
Disable transformations and optimizations that assume default floating-point rounding behavior. This is round-to-zero for all floating point to integer conversions, and round-to-nearest for all other arithmetic truncations. This option should be specified for programs that change the FP rounding mode dynamically, or that may be executed with a non-default rounding mode. This option disables constant folding of floating-point expressions at compile time (which may be affected by rounding mode) and arithmetic transformations that are unsafe in the presence of sign-dependent rounding modes.
-f-signaling-nans
Compile code assuming that IEEE signaling NaNs may generate user-visible traps during floating-point operations. Setting this option disables optimizations that may change the number of exceptions visible with signaling NaNs. This option implies -ftrapping-math.
This option causes the preprocessor macro __SUPPORT_SNAN__ to be defined.
-fcx-limited-range
When enabled, this option states that a range reduction step is not needed when performing complex division. Also, there is no checking whether the result of a complex multiplication or division is NaN + I*NaN, with an attempt to rescue the situation in that case. The default is -fno-cx-limited-range, but is enabled by -ffast-math.
This option controls the default setting of the ISO C99 CX_LIMITED_RANGE pragma. Nevertheless, the option applies to all languages.
-fexcess-precision=style
This option allows further control over excess precision on machines where floating-point operations occur in a format with more precision or range than the IEEE standard and interchange floating-point types. By default, -fexcess-precision=fast is in effect; this means that operations may be carried out in a wider precision than the types specified in the source if that would result in faster code, and it is unpredictable when rounding to the types specified in the source code takes place. When compiling C, if -fexcess-precision=standard is specified then excess precision follows the rules specified in ISO C99; in particular, both casts and assignments cause values to be rounded to their semantic types (whereas -ffloat-store only affects assignments). This option is enabled by default for C if a strict conformance option such as -std=c99 is used. -ffast-math enables -fexcess-precision=fast by default regardless of whether a strict conformance option is used.
-fexcess-precision=standard is not implemented for languages other than C. On the x86, it has no effect if -mfpmath=sse or -mfpmath=sse+387 is specified; in the former case, IEEE semantics apply without excess precision, and in the latter, rounding is unpredictable.
Das ist eine ganze Menge. Viele Sachen klingen für mich, als wenn einfach jede Menge if/else Zweige raus genommen werden. Und ich denke diese Optimierungen wirken für double wie für float. Das erklärt noch nicht den Geschwindigkeitsunterschied im letzten Post. Da muss ich wohl mal in den Assembler Code schaun.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
https://gcc.gnu.org/wiki/FloatingPointMath
C++ Guns - Bartek's coding blog - Float vs Double - Überprüft
Wieder so ein C++ Blog, der aber in Wahrheit scheiß C Code verbreitet. Und dann erzählt er auch noch die Hälfte und macht unvollständige Angaben zu seinen Tests.
Es geht in dem Artikel darum, dass viele denken, dass floats kleiner und schneller als doubles sein. Kleiner sind sie, ja. Verbrauchen nur 4 Byte statt 8 Byte. Aber schneller sind sie nicht unbedingt. Sollten doch unsere heutigen CPUs mit genügen Hardware ausgestattet sein, um auch 64 Bit Zahlen genauso schnell zu verarbeiten. Na, wir werden sehen...
Endergebnis für ungeduldige:
Für kleine Datenmengen und IEEE Gleitkommazahlen verhalten sich bei meinen Tests floats und doubles gleich.
Verzichtet man auf Standard Zahlen und aktiviert fancy Optimierungen, wird man mit einem 1.5 bis 3.5-fachen schnelleren Programm belohnt, welches falsche Ergebnisse liefern kann.
Für große Mengen sieht die Sache anders aus. Dann wird der RAM Bus zum Flaschenhals.
Im ersten Teil übernehme ich sein Code und versuche die selben Ergebnisse zu erzielen. Im zweiten Teil schreibe ich das ganze nach C++ um. Leider gibt er nicht an, wie groß das Array sein soll und wie viele Iterationen gerechnet werden sollen. Also hab ich mal irgendwas eingestellt um ein paar Sekunden Laufzeit zu bekommen. Wenn man wie im original Artikel nur unter einer Sekunde misst, ist die Varianz zu hoch, und man weiß gar nichts.
Testfall:
AMD Athlon(tm) 64 X2 Dual Core Processor 4800+
32Bit Debian
g++ 6.3.0
ARR_SIZE = 200000
NUM_ITER = 20000
Die Standardeinstellung für 64 Bit Systeme mit Optimierung ist SSE. Ich werde daher explizit auf den floating-point Coprozessor mit der Option -mfpmath=387 umschalten. Für SSE werde ich die Option -mfpmath=sse -msse2 benutzen.
Die Option -ffast-math kann übrigens falsche Ergebnisse liefern. Die exakten Vorgaben der IEEE Spezifikationen werden nicht eingehalten. Dafür sollte man ein schnelleres Programm haben.
Mittelwert von drei Berechnungen pro Einstellung. Alle Angaben in Sekunden.
-O3 -mfpmath=387 | -O3 -mfpmath=sse -msse2 | -O3 -mfpmath=387 -ffast-math | -O3 -mfpmath=sse -msse2 -ffast-math | |
float | 6.54 | 6.56 | 6.52 | 2.01 |
double | 6.61 | 6.78 | 6.54 | 4.54 |
Also, dasss floats schneller sind als doubles, oder dass doubles schneller sind als floats kann ich in diesem Testfall nicht bestätigen. Bei mir sind sie im Grunde gleich schnell. Nur die Option -ffast-math bewirkt eine Geschwindigkeitsverbesserung um das 3-fache bzw. 1.5-fache.
Aber das kann von CPU zu CPU anders sein. Vor allen von microshit zu GNU.
Testfall 2:
Intel(R) Atom(TM) CPU N270 @ 1.60GHz
32 Bit Debian
g++ 4.9.2
ARR_SIZE = 200000
NUM_ITER = 20000
Mittelwert von drei Berechnungen pro Einstellung. Alle Angaben in Sekunden.
-O3 -mfpmath=387 | -O3 -mfpmath=sse -msse2 | -O3 -mfpmath=387 -ffast-math | -O3 -mfpmath=sse -msse2 -ffast-math | |
float | 21.1 | 18.9 | 21.1 | 6.19 |
double | 22.2 | 22.2 | 22.2 | 31.6 |
Durch den Sparstrumpf Prozessor zeigt sich insgesamt eine höhere Laufzeit. Floats und doubles sind wieder in etwa gleich schnell. Nur die -ffast-math Option macht einen Unterschied. Für floats eine Verbesserung der Laufzeit wieder um das 3-fache. Und für doubles sehe ich sogar eine Verschlechterung um das 1.5-fache. Das müsste man jetzt versuchen zu erklären...
Testfall3:
AMD FX(tm)-9590 Eight-Core Processor
64 bit Debian
g++ 4.9.2
ARR_SIZE = 200000
NUM_ITER = 20000
Mittelwert von drei Berechnungen pro Einstellung. Alle Angaben in Sekunden.
-O3 -mfpmath=387 | -O3 -mfpmath=sse -msse2 | -O3 -mfpmath=387 -ffast-math | -O3 -mfpmath=sse -msse2 -ffast-math | |
float | 4.45 | 4.47 | 1.12 | 1.17 |
double | 4.45 | 4.45 | 2.35 | 2.34 |
Die Laufzeit fällt insgesamt, verursacht durch mehr GHz Power. Bis auf -ffast-math sind floats und doubles wieder gleich schnell. Der Geschwindigkeitsvorteil für fast-math liegt wieder bei über 3.5-fach für floats und über 1.5-fach für doubles.
Endergebnis:
Für kleine Datenmengen und IEEE Gleitkommazahlen verhalten sich floats und doubles gleich.
Verzichtet man auf Standard Zahlen und aktiviert fancy Optimierungen, wird man mit einem 1.5 bis 3.5-fachen schnelleren Programm belohnt, welches falsche Ergebnisse liefern kann.
Für große Mengen sieht die Sache anders aus. Dann wird der RAM Bus zum Flaschenhals.
Warum verhält sich die Geschwindigkeit mit -ffast-math so unterschiedlich? Das muss man genauer untersuchen.
http://www.bfilipek.com/2012/05/float-vs-double.html