Podnormální číslo - Subnormal number

Neupravený systém s plovoucí desetinnou čárkou by obsahoval pouze normalizovaná čísla (označená červeně). Povolení denormalizovaných čísel (modrá) rozšiřuje dosah systému.

Ve výpočetní technice jsou subnormální čísla podmnožinou denormalizovaných čísel (někdy nazývaných denormály ), které vyplňují mezeru pod proudem kolem nuly v aritmetice s pohyblivou řádovou čárkou . Jakékoli nenulové číslo o velikosti menší než nejmenší normální číslo je podnormální .

Poznámka k použití: v některých starších dokumentech (zejména standardních dokumentech, jako jsou počáteční verze IEEE 754 a jazyk C )) se „denormal“ používá pouze k označení podnormálních čísel. Toto použití přetrvává v různých standardních dokumentech, zejména při diskusi o hardwaru, který není schopen reprezentovat jakákoli jiná denormalizovaná čísla, ale diskuse zde používá termín subnormální v souladu s revizí IEEE 754 z roku 2008 .

V normální hodnotě s plovoucí desetinnou čárkou neexistují žádné úvodní nuly v manténě ( mantisa ); úvodní nuly jsou spíše odstraněny úpravou exponentu (například číslo 0,0123 bude zapsáno jako 1,23 × 10 −2 ). Naopak denormalizovaná hodnota s plovoucí desetinnou čárkou má význam s počáteční číslicí nula. Z nich subnormální čísla představují hodnoty, které by při normalizaci měly exponenty pod nejmenším reprezentovatelným exponentem (exponent s omezeným rozsahem).

Význam (nebo mantisa) čísla IEEE s plovoucí desetinnou čárkou je část čísla s plovoucí desetinnou čárkou, která představuje platné číslice . Pro kladné normalizované číslo může být reprezentováno jako m 0 . m 1 m 2 m 3 ... m p −2 m p −1 (kde m představuje významnou číslici a p je přesnost) s nenulovým m 0 . Všimněte si, že pro binární radix je úvodní binární číslice vždy 1. V subnormálním čísle, protože exponent je to nejmenší, co může být, je nula přední významná číslice (0 m 1 m 2 m 3 ... m p −2 m p −1 ), což umožňuje reprezentaci čísel blíže nule než nejmenší normální číslo. Číslo s plovoucí desetinnou čárkou může být uznáno jako subnormální, kdykoli je jeho exponent nejmenší možná hodnota.

Vyplněním mezery podtečení tímto způsobem dojde ke ztrátě významných číslic, ale ne tak náhle, jako při použití metody flush to zero při podtečení (vyřazení všech významných číslic, když je dosaženo podtečení). Proto je produkce podnormálního čísla někdy nazývána postupným podtečením, protože umožňuje výpočtu pomalu ztrácet přesnost, když je výsledek malý.

V IEEE 754-2008 jsou denormální čísla přejmenována na subnormální čísla a jsou podporována v binárním i desítkovém formátu. Ve formátech binární výměny jsou subnormální čísla kódována zkresleným exponentem 0, ale jsou interpretována s hodnotou nejmenšího povoleného exponentu, který je o jeden větší (tj. Jako by byl kódován jako 1). V desítkových výměnných formátech nevyžadují žádné speciální kódování, protože formát přímo podporuje nenormalizovaná čísla.

Matematicky řečeno, normalizovaná čísla s plovoucí desetinnou čárkou daného znaménka jsou zhruba logaritmicky rozmístěna a jako takový nemůže žádný normální plovák konečných velikostí obsahovat nulu . Subnormální plováky jsou lineárně rozmístěnou sadou hodnot, které překlenují mezeru mezi záporným a kladným normálním plovákem.

Pozadí

Podnormální čísla poskytují záruku, že sčítání a odčítání čísel s plovoucí desetinnou čárkou nikdy nepřeteče; dvě blízká čísla s plovoucí desetinnou čárkou mají vždy reprezentativní nenulový rozdíl. Bez postupného podtečení může odčítání a  -  b přetékat a vytvářet nulu, i když hodnoty nejsou stejné. To může zase vést k dělení nulovými chybami, ke kterým nemůže dojít při použití postupného podtečení.

Během psaní standardu IEEE 754 byla do procesoru Intel 8087 implementována podnormální čísla . Byly zdaleka nejkontroverznějším prvkem v návrhu formátu KCS, který byl nakonec přijat, ale tato implementace ukázala, že při praktické implementaci lze podpořit podnormální čísla. Některé implementace jednotek s plovoucí desetinnou čárkou přímo nepodporují podnormální čísla v hardwaru, ale spíše pasti na nějaký druh softwarové podpory. I když to může být pro uživatele transparentní, může to mít za následek, že výpočty, které produkují nebo spotřebovávají subnormální čísla, jsou mnohem pomalejší než podobné výpočty na normálních číslech.

Problémy s výkonem

Některé systémy zpracovávají subnormální hodnoty v hardwaru stejným způsobem jako normální hodnoty. Jiní nechávají zpracování podnormálních hodnot na systémovém softwaru („pomáhat“), pouze zpracovávají normální hodnoty a v hardwaru nulu. Zpracování podnormálních hodnot v softwaru vždy vede k významnému snížení výkonu. Když jsou subnormální hodnoty zcela počítány v hardwaru, existují implementační techniky, které umožňují jejich zpracování rychlostí srovnatelnou s běžnými čísly. Na mnoha moderních procesorech x86 však rychlost výpočtu zůstává výrazně snížena; v extrémních případech mohou instrukce zahrnující subnormální operandy trvat až 100 dalších hodinových cyklů, což způsobí, že nejrychlejší instrukce poběží až šestkrát pomaleji.

Tento rozdíl v rychlosti může představovat bezpečnostní riziko. Výzkumníci ukázali, že poskytuje postranní kanál časování, který umožňuje škodlivému webu extrahovat obsah stránky z jiného webu do webového prohlížeče.

Některé aplikace musí obsahovat kód, aby se vyhnuly podnormálním číslům, ať už kvůli zachování přesnosti, nebo aby se vyhnuly penalizaci výkonu v některých procesorech. Například v aplikacích pro zpracování zvuku subnormální hodnoty obvykle představují signál tak tichý, že je mimo dosah lidského sluchu. Z tohoto důvodu je běžným opatřením, jak se vyhnout podnormálům na procesorech, kde by došlo k penalizaci výkonu, snížení signálu na nulu, jakmile dosáhne subnormálních úrovní, nebo smíchání extrémně tichého šumového signálu. Mezi další způsoby prevence subnormálních čísel patří přidání DC offsetu, kvantování čísel, přidání Nyquistova signálu atd. Od rozšíření procesoru SSE2 poskytuje Intel takovou funkci v hardwaru CPU, která zaokrouhluje subnormální čísla na nulu.

Deaktivace subnormálních plováků na úrovni kódu

Intel SSE

Kompilátory C a Fortran společnosti Intel ve výchozím nastavení povolují příznaky DAZ(denormals-are-zero) a FTZ(flush-to-zero) pro SSE pro úrovně optimalizace vyšší než -O0. Účinek DAZje léčba vstupní podnormální argumentů, s plovoucí desetinnou čárkou operace jako nula, a účinek FTZje vrátit nula namísto subnormální plovákem pro operace, které by vedly k subnormální plováku, a to i v případě, že vstupní argumenty nejsou samy o sobě podnormální. clang a gcc mají různé výchozí stavy v závislosti na platformě a úrovni optimalizace.

Která není C99 -kompatibilní způsob umožnit DAZa FTZpříznaky na cíle nosných SSE je uvedeno níže, ale není široce podporován. Je známo, že funguje na Mac OS X nejméně od roku 2006.

#include <fenv.h>
#pragma STDC FENV_ACCESS ON
// Sets DAZ and FTZ, clobbering other CSR settings.
// See https://opensource.apple.com/source/Libm/Libm-287.1/Source/Intel/, fenv.c and fenv.h.
fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
// fesetenv(FE_DFL_ENV) // Disable both, clobbering other CSR settings.

Pro jiné platformy x86-SSE, kde knihovna C dosud tento příznak neimplementovala, může fungovat následující:

#include <xmmintrin.h>
_mm_setcsr(_mm_getcsr() | 0x0040);  // DAZ
_mm_setcsr(_mm_getcsr() | 0x8000);  // FTZ
_mm_setcsr(_mm_getcsr() | 0x8040);  // Both
_mm_setcsr(_mm_getcsr() & ~0x8040); // Disable both

_MM_SET_DENORMALS_ZERO_MODEA _MM_SET_FLUSH_ZERO_MODEmakra zabalit srozumitelnější rozhraní pro kód výše.

// To enable DAZ
#include <pmmintrin.h>
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
// To enable FTZ
#include <xmmintrin.h>
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);

Většina kompilátorů již ve výchozím nastavení poskytuje předchozí makro, jinak lze použít následující fragment kódu (definice pro FTZ je analogická):

#define _MM_DENORMALS_ZERO_MASK   0x0040
#define _MM_DENORMALS_ZERO_ON     0x0040
#define _MM_DENORMALS_ZERO_OFF    0x0000

#define _MM_SET_DENORMALS_ZERO_MODE(mode) _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (mode))
#define _MM_GET_DENORMALS_ZERO_MODE()                (_mm_getcsr() &  _MM_DENORMALS_ZERO_MASK)

Výchozí chování denormalizace je nařízeno ABI , a proto by dobře vychovaný software měl uložit a obnovit režim denormalizace před návratem k volajícímu nebo volání kódu v jiných knihovnách.

PAŽE

AArch32 NEON (SIMD) FPU vždy používá režim flush-to-zero, který je stejný jako FTZ + DAZ. U skalárního FPU a v AArch64 SIMD je chování flush-to-zero volitelné a je řízeno FZbitem řídicího registru-FPSCR v Arm32 a FPCR v AArch64.

Některé procesory ARM mají hardwarové zpracování subnormálů.

Viz také

Reference

Další čtení

  • Viz také různé dokumenty na webových stránkách Williama Kahana [1], kde najdete příklady, kde subnormální čísla pomáhají zlepšit výsledky výpočtů.