A meia precisão (às vezes chamada de FP16 ou float16) é um formato de número de ponto flutuante binário que ocupa 16 bits (dois bytes em computadores modernos) na memória do computador. Ele é destinado ao armazenamento de valores de ponto flutuante em aplicações onde uma precisão mais alta não é essencial, em particular no processamento de imagens e em redes neurais. Quase todos os usos modernos seguem o padrão IEEE 754-2008, no qual o formato de base 2 de 16 bits é referido como binary16, e o expoente utiliza 5 bits. Este formato pode expressar valores no intervalo de ±65.504, sendo o valor mínimo acima de 1 igual a

1 +

1 1024

{\displaystyle 1+{\frac {1}{1024}}}

.

História Vários formatos anteriores de ponto flutuante de 16 bits existiram, incluindo o do DSP HD61810 da Hitachi de 1982 (um expoente de 4 bits e uma mantissa de 12 bits), os 16 bits superiores de um float de 32 bits (8 bits de expoente e 7 de mantissa) chamado de bfloat16, o WIF de Thomas J. Scott de 1991 (5 bits de expoente, 10 bits de mantissa) e o processador gráfico da 3dfx Voodoo Graphics de 1995 (igual ao da Hitachi). A ILM buscava um formato de imagem que pudesse lidar com um amplo alcance dinâmico, mas sem o custo de disco rígido e memória de um ponto flutuante de precisão simples ou dupla. O grupo de sombreamento (shading) programável acelerado por hardware liderado por John Airey na SGI (Silicon Graphics) utilizou o tipo de dado s10e5 em 1997 como parte do esforço de projeto "bali". Isso é descrito em um artigo da SIGGRAPH de 2000 (ver seção 4.3) e posteriormente documentado na patente dos EUA 7518615. O formato foi popularizado pelo seu uso no formato de imagem de código aberto OpenEXR. A Nvidia e a Microsoft definiram o tipo de dado half na linguagem Cg, lançada no início de 2002, e o implementaram em silício na GeForce FX, lançada no final de 2002. No entanto, o suporte por hardware para ponto flutuante de 16 bits acelerado foi posteriormente descontinuado pela Nvidia, antes de ser reintroduzido na GPU móvel Tegra X1 em 2015. A extensão F16C em 2012 permitiu que os processadores x86 convertessem floats de meia precisão de e para floats de precisão simples com uma instrução de máquina.

Formato de ponto flutuante binário de meia precisão IEEE 754: binary16 O padrão IEEE 754 especifica que um binary16 possui o seguinte formato:

Bit de sinal: 1 bit Largura do expoente: 5 bits Precisão do significando: 11 bits (10 explicitamente armazenados) O formato é disposto da seguinte forma:

O formato assume um bit condutor implícito com valor 1, a menos que o campo do expoente esteja armazenado com todos os zeros. Assim, apenas 10 bits do significando aparecem no formato de memória, mas a precisão total é de 11 bits (log10(211) ≈ 3,311 dígitos decimais, ou 4 dígitos ± ligeiramente menos que 5 unidades na última posição).

Codificação do expoente O expoente de ponto flutuante binário de meia precisão é codificado usando uma representação em binário deslocado, com o deslocamento zero sendo 15; também conhecido como viés do expoente no padrão IEEE 754.

Emin = 000012 − 011112 = −14 Emax = 111102 − 011112 = 15 Viés do expoente = 011112 = 15 Assim, conforme definido pela representação em binário deslocado, para obter o expoente verdadeiro, o deslocamento de 15 deve ser subtraído do expoente armazenado. Os expoentes armazenados 000002 and 111112 são interpretados de forma especial.

O menor valor estritamente positivo (subnormal) é

2

− 24

≈ 5 , 96 ×

10

− 8

{\displaystyle 2^{-24}\approx 5,96\times 10^{-8}}

. O menor valor normal positivo é

2

− 14

≈ 6 , 10 ×

10

− 5

{\displaystyle 2^{-14}\approx 6,10\times 10^{-5}}

. O valor máximo representável é

( 2 −

2

− 10

) ×

2

15

= 65504

{\displaystyle (2-2^{-10})\times 2^{15}=65504}

.

Exemplos de meia precisão Estes exemplos são dados na representação de bits do valor de ponto flutuante. Isso inclui o bit de sinal, o expoente (com viés) e o significando.

Por padrão, 1/3 arredonda para baixo como ocorre na precisão dupla, devido ao número ímpar de bits no significando. Os bits além do ponto de arredondamento são 0101..., o que é menor que 1/2 de uma unidade na última posição.

Meia precisão alternativa ARM Os processadores ARM suportam (por meio de um bit no registrador de controle de ponto flutuante) um formato de "meia precisão alternativa", que elimina o caso especial para um valor de expoente igual a 31 (111112). Ele é quase idêntico ao formato IEEE, mas não há codificação para infinito ou NaNs; em vez disso, um expoente de 31 codifica números normais no intervalo de 65.536 a 131.008.

Usos da meia precisão A meia precisão é utilizada em vários ambientes de computação gráfica para armazenar pixels, incluindo o MATLAB, OpenEXR, JPEG XR, GIMP, OpenGL, Vulkan, Cg, Direct3D e D3DX. A vantagem em relação aos inteiros de 8 ou 16 bits é que o maior alcance dinâmico permite que mais detalhes sejam preservados nos realces e sombras das imagens, além de evitar a correção gama. A vantagem em relação ao ponto flutuante de precisão simples de 32 bits é que ele requer metade do armazenamento e da largura de banda (à custa da precisão e do intervalo). A meia precisão pode ser útil para a quantização de malhas poligonais. Os dados de malha geralmente são armazenados usando floats de precisão simples de 32 bits para os vértices; no entanto, em algumas situações é aceitável reduzir a precisão para meia precisão de 16 bits, exigindo apenas metade do armazenamento à custa de alguma fidelidade. A quantização de malha também pode ser feita com precisão fixa de 8 ou 16 bits, dependendo dos requisitos. Hardwares e softwares para aprendizado de máquina e redes neurais frequentemente usam aritmética de meia precisão para acelerar as computações. Nessas aplicações, o formato distinto bfloat16 às vezes é preferido por seu alcance dinâmico mais amplo do que a meia precisão, e formatos especializados de ponto flutuante com apenas 8 bits ou menos são cada vez mais utilizados para acelerar ainda mais certos cálculos. Se o hardware possui instruções para computar matemática de meia precisão, ela é frequentemente mais rápida do que a precisão simples ou dupla, chegando às vezes a ser até 4 vezes mais rápida. Além disso, se o sistema possui instruções SIMD, uma única instrução pode frequentemente operar simultaneamente no dobro de valores de meia precisão em comparação com os valores tradicionais de float.

Suporte por linguagens de programação As linguagens Zig, Odin e outras fornecem suporte nativo para meia precisão com o seu tipo f16. O .NET 5 introduziu números de ponto flutuante de meia precisão com o tipo System.Half da biblioteca padrão. Até o momento, nenhuma linguagem .NET (C#, F#, Visual Basic, C++/CLI e C++/CX) possui literais ou uma palavra-chave dedicada para o tipo. A linguagem Swift introduziu números de ponto flutuante de meia precisão no Swift 5.3 com o tipo Float16. O OpenCL também suporta números de ponto flutuante de meia precisão com o tipo de dado half no formato de armazenamento de meia precisão IEEE 754-2008. A linguagem Rust está atualmente trabalhando na adição de um novo tipo f16 para floats de 16 bits de meia precisão IEEE. O Julia fornece suporte para números de ponto flutuante de meia precisão com o tipo Float16. O C++ introduziu a meia precisão a partir do C++23 com o tipo std::float16_t. O compilador GCC já implementa suporte para ele.

Suporte por hardware Várias versões da arquitetura ARM possuem suporte nativo para meia precisão. O suporte para conversões com floats de meia precisão no conjunto de instruções x86 é especificado na extensão do conjunto de instruções F16C, introduzida pela primeira vez em 2009 pela AMD e amplamente adotada pelas CPUs AMD e Intel por volta de 2012. Isso foi estendido pela extensão do conjunto de instruções AVX-512_FP16, implementada no processador Intel Sapphire Rapids. No RISC-V, as extensões Zfh e Zfhmin fornecem suporte por hardware para floats de 16 bits de meia precisão. A extensão Zfhmin é uma alternativa mínima à Zfh. Na Arquitetura Power, o VSX e a extensão SVP64 fornecem suporte por hardware para floats de 16 bits de meia precisão a partir da especificação PowerISA v3.1B e posteriores. O suporte para meia precisão no IBM Z faz parte do recurso de assistência de processamento de rede neural que a IBM introduziu com o processador Telum. A IBM refere-se aos dados de ponto flutuante de meia precisão como NNP-Data-Type 1 (16-bit).

Veja também Formato de ponto flutuante bfloat16: formato alternativo de ponto flutuante de 16 bits com 8 bits de expoente e 7 bits de mantissa Minifloat: formatos pequenos de ponto flutuante

Referências

Leitura adicional Formato Khronos Vulkan de ponto flutuante de 16 bits com sinal

Ligações externas Minifloats (em Survey of Floating-Point Formats) Site oficial do OpenEXR