Portál AbcLinuxu, 3. května 2025 02:09
Existují na to dokonce řídící registry, kde se to nastavuje.A funkce v glibc.
Many programmers like to believe that they can understand the semantics of a program and prove that it will work correctly without reference to the compiler that compiles it or the computer that runs it. In many ways, supporting this belief is a worthwhile goal for the designers of computer systems and programming languages. Unfortunately, when it comes to floating-point arithmetic, the goal is virtually impossible to achieve. The authors of the IEEE standards knew that, and they didn't attempt to achieve it. As a result, despite nearly universal conformance to (most of) the IEEE 754 standard throughout the computer industry, programmers of portable software will have to continue to cope with unpredictable floating-point arithmetic for the foreseeable future.(zdroj)
Když zkompiluješ Linux (opravdu pouze kernel) s flagem pro Pentium II a spustíš ho na procesoru Cyrix 686, spadné ESP Ghostscript jako domeček z karet kvůli underflow. (=> Pak to vůbec netiskne...) S flagem Pentium-Pro funguje bez potíží. Paradoxní je, že nebylo nutné překompilovat samotný Ghostscript. (Ten byl v obou případech z binárního balíčku s flagem Pentium-Pro.)
Takže můj intuitivní úsudek je: Ano, může se to stát.
temp1 = y*x
temp2 = x*y (ale na pořadí samozřejmě nezáleží)
imag_slozka = temp1-temp2
což by byla skutečně ryzí nula, nýbrž jako
temp1 = y*x
imag_slozka = temp1 - x*y
Z hlediska vnesení zaokrouhlovacích chyb, mezi dvěma výše uvedenými kroky je samozřejmě výrazný rozdíl. V prvním případě jde o tři operace, a tak je zaokrouhlovací chyba vnesena třikrát. Ve druhém (FMA) případě je zaokrouhlování prováděno pouze dvakrát.
Že si nevymýšlím, je možné vidět na následujícím příkladě v Octave
octave:1> A = rand(3,3) + j*rand(3,3)
A =
0.20974 + 0.43455i 0.50108 + 0.38016i 0.24643 + 0.90169i
0.33751 + 0.39598i 0.22127 + 0.58548i 0.58724 + 0.88980i
0.84237 + 0.18959i 0.67795 + 0.99298i 0.33828 + 0.00156i
octave:2> C = rand(3,3) + j*rand(3,3)
C =
0.213787 + 0.961981i 0.469730 + 0.922373i 0.560915 + 0.462651i
0.930401 + 0.763539i 0.146290 + 0.423445i 0.015814 + 0.004987i
0.286520 + 0.579304i 0.581899 + 0.806029i 0.685377 + 0.171148i
octave:3> A = C'*C
A =
2.83744 - 0.00000i 2.08081 - 0.07856i 0.87902 - 0.79612i
2.08081 + 0.07856i 2.26041 + 0.00000i 1.23141 - 0.75886i
0.87902 + 0.79612i 1.23141 + 0.75886i 1.02798 - 0.00000i
octave:4> A - A'
ans =
0.00000 - 0.00000i 0.00000 + 0.00000i 0.00000 + 0.00000i
0.00000 + 0.00000i 0.00000 + 0.00000i 0.00000 + 0.00000i
0.00000 + 0.00000i 0.00000 + 0.00000i 0.00000 - 0.00000i
Na první pohled to možná vypadá, že jsme skutečně dostali nulu, ale nenechte se zmást:
octave:5> format hex
octave:6> A - A'
ans =
Columns 1 and 2:
0000000000000000 bc91200000000000i 0000000000000000 3c90000000000000i
0000000000000000 3c90000000000000i 0000000000000000 3c70800000000000i
0000000000000000 0000000000000000i 0000000000000000 0000000000000000i
Column 3:
0000000000000000 0000000000000000i
0000000000000000 0000000000000000i
0000000000000000 bc8a000000000000i
Shrnutí: při srovnávání výsledků numerických výpočtů na různých platformách je nutné dnes brát i v úvahu přítomnost či absenci, povolení či zakázání některých novějších technologií jako například FMA (a možná i jiné, nevím, nejsem expert).
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.