# Fermi (microarquitetura)

Fermi é o codinome da microarquitetura de unidade de processamento gráfico (GPU) desenvolvida pela Nvidia, lançada pela primeira vez no varejo em abril de 2010, como sucessora da microarquitetura Tesla. Foi a principal microarquitetura usada nas séries GeForce 400 e GeForce 500. Foi seguido pelo Kepler, e usado junto com o Kepler nas séries GeForce 600, GeForce 700 e GeForce 800, nas duas últimas apenas em GPUs móveis. No mercado de estações de trabalho, Fermi encontrou uso na série Quadro x000, modelos Quadro NVS, bem como em módulos de computação Nvidia Tesla. Todas as GPUs Fermi de desktop foram fabricadas em 40nm, GPUs Fermi móveis em 40nm e 28nm.$^[$ Fermi é a microarquitetura mais antiga da NVIDIA que recebeu suporte paraa API de renderização Direct3D 12 feature_level 11 da Microsoft.
A arquitetura leva o nome de Enrico Fermi, um físico italiano.

## Visão geral

As unidades de processamento gráfico Fermi (GPUs) apresentam 3,0 bilhões de transistores e um esquema é esboçado na Figura 1.
* Multiprocessador de streaming (SM): composto por 32 núcleos CUDA (consulte as seções Multiprocessador de streaming e núcleo CUDA).
* Agendador global GigaThread: distribui blocos de threads para agendadores de threads SM e gerencia as trocas de contexto entre threads durante a execução (consulte a seção Warp Scheduling).
* Interface host: conecta a GPU à CPU através de um barramento PCI-Express v2 (taxa de transferência máxima de 8 GB/s).
* DRAM: suporta até 6 GB de memória DRAM GDDR5 graças à capacidade de endereçamento de 64 bits (consulte a seção Arquitetura de memória).
* Frequência de clock: 1,5 GHz (não divulgada pela NVIDIA, mas estimada pelo Insight 64).
* Desempenho máximo: 1,5 TFlops.
* Relógio de memória global: 2 GHz.
* Largura de banda DRAM: 192GB/s.

## Multiprocessador de streaming

Cada SM possui 32 núcleos CUDA de precisão única, 16 unidades de carga/armazenamento, quatro Unidades de Função Especial (SFUs), um bloco de 64 KB de memória on-chip de alta velocidade (consulte a subseção L1+Memória Compartilhada) e uma interface para o cache L2 (consulte a subseção Cache L2).

### Carregar/Armazenar Unidades

Permitir que os endereços de origem e destino sejam calculados para 16 threads por clock. Carregue e armazene os dados de/para cache ou DRAM.

### Unidades de Funções Especiais (SFUs)

Execute instruções transcendentais como sin, cosseno, recíproco e raiz quadrada. Cada SFU executa uma instrução por thread, por clock; um warp é executado em oito clocks. O pipeline SFU é desacoplado da unidade de despacho, permitindo que a unidade de despacho emita para outras unidades de execução enquanto a SFU está ocupada.

## CUDA core

Unidade Lógica Aritmética Inteira (ALU): Suporta precisão total de 32 bits para todas as instruções, consistente com os requisitos de linguagem de programação padrão. Ele também é otimizado para suportar com eficiência operações de precisão estendida e de 64 bits.

### Unidade de ponto flutuante (FPU)

Implementa o novo padrão de ponto flutuante IEEE 754-2008, fornecendo a instrução de adição multiplicada fundida (FMA) para aritmética de precisão simples e dupla. Até 16 operações de adição e multiplicação fundidas de precisão dupla podem ser executadas por SM, por clock.

## Multiplicação-adição fundida

Fused multiply-add (FMA) realiza multiplicação e adição (ou seja, A*B+C) com uma única etapa de arredondamento final, sem perda de precisão na adição. O FMA é mais preciso do que realizar as operações separadamente.

## Programação de dobra

A arquitetura Fermi usa um escalonador de threads distribuído de dois níveis.
Cada SM pode emitir instruções consumindo quaisquer duas das quatro colunas de execução verdes mostradas no esquema da Fig. 1. Por exemplo, o SM pode misturar 16 operações dos 16 núcleos da primeira coluna com 16 operações dos 16 núcleos da segunda coluna, ou 16 operações das unidades de carga/armazenamento com quatro de SFUs ou quaisquer outras combinações especificadas pelo programa.
Observe que as operações de ponto flutuante de 64 bits consomem as duas primeiras colunas de execução. Isto implica que um SM pode emitir até 32 operações de ponto flutuante de precisão simples (32 bits) ou 16 operações de ponto flutuante de precisão dupla (64 bits) por vez.

### Mecanismo GigaThread

O mecanismo GigaThread agenda blocos de threads para vários SMs.

### Agendador de Dual Warp

No nível SM, cada escalonador de warp distribui warps de 32 threads para suas unidades de execução. Os threads são agendados em grupos de 32 threads chamados warps. Cada SM possui dois escalonadores de warp e duas unidades de despacho de instruções, permitindo que dois warps sejam emitidos e executados simultaneamente. O agendador de warp duplo seleciona dois warps e emite uma instrução de cada warp para um grupo de 16 núcleos, 16 unidades de carga/armazenamento ou 4 SFUs. A maioria das instruções pode ser emitida duplamente; duas instruções inteiras, duas instruções flutuantes ou uma combinação de instruções inteiras, ponto flutuante, carregamento, armazenamento e SFU podem ser emitidas simultaneamente. Instruções de precisão dupla não suportam despacho duplo com qualquer outra operação.$^[$

## Desempenho

O poder teórico de processamento de precisão única de uma GPU Fermi em GFLOPS é calculado como 2 (operações por instrução FMA por núcleo CUDA por ciclo) × número de núcleos CUDA × velocidade de clock do shader (em GHz). Observe que a geração anterior do Tesla poderia emitir MAD + MUL para núcleos CUDA e SFUs em paralelo, mas Fermi perdeu essa capacidade, pois só pode emitir 32 instruções por ciclo por SM, o que mantém apenas seus 32 núcleos CUDA totalmente utilizados. Portanto, não é possível aproveitar os SFUs para atingir mais de 2 operações por núcleo CUDA por ciclo.
O poder teórico de processamento de precisão dupla de uma GPU Fermi é 1/2 do desempenho de precisão simples do GF100/110. No entanto, na prática, esse poder de precisão dupla está disponível apenas em placas Quadro e Tesla profissionais, enquanto as placas GeForce de consumo são limitadas a 1/8.

## Memória

Cache L1 por SM e cache L2 unificado que atende todas as operações (carregamento, armazenamento e textura).

### Registros

Cada SM possui 32K de registros de 32 bits. Cada thread tem acesso aos seus próprios registros e não aos de outras threads. O número máximo de registros que podem ser usados ​​por um kernel CUDA é 63. O número de registros disponíveis diminui normalmente de 63 para 21 à medida que a carga de trabalho (e, portanto, os requisitos de recursos) aumenta pelo número de threads. Os registros têm uma largura de banda muito alta: cerca de 8.000 GB/s.

### L1+Memória compartilhad a

Memória no chip que pode ser usada para armazenar dados em cache para threads individuais (registro derramado/cache L1) e/ou para compartilhar dados entre vários threads (memória compartilhada). Essa memória de 64 KB pode ser configurada como 48 KB de memória compartilhada com 16 KB de cache L1 ou 16 KB de memória compartilhada com 48 KB de cache L1. A memória compartilhada permite que threads dentro do mesmo bloco de threads cooperem, facilita a reutilização extensiva de dados no chip e reduz bastante o tráfego fora do chip. A memória compartilhada é acessível pelos threads no mesmo bloco de threads. Ele fornece acesso de baixa latência (10 a 20 ciclos) e largura de banda muito alta (1.600 GB/s) para quantidades moderadas de dados (como resultados intermediários em uma série de cálculos, uma linha ou coluna de dados para operações de matriz, uma linha de vídeo, etc.). David Patterson diz que esta memória compartilhada usa a ideia de scratchpad local.

### Memória local

A memória local é um local de memória usado para armazenar registros "derramados". O derramamento de registradores ocorre quando um bloco de thread requer mais armazenamento de registradores do que o disponível em um SM. A memória local é usada apenas para algumas variáveis ​​automáticas (que são declaradas no código do dispositivo sem nenhum dos qualificadores __device__, __shared__, ou __constant__). Geralmente, uma variável automática reside em um registrador, exceto no seguinte: (1) Arrays que o compilador não consegue determinar são indexados com quantidades constantes; (2) Grandes estruturas ou arrays que consumiriam muito espaço de registro; Qualquer variável que o compilador decida enviar para a memória local quando um kernel usa mais registros do que os disponíveis no SM.

### Cache L2

Cache L2 unificado de 768 KB, compartilhado entre os 16 SMs, que atende toda a carga e armazenamento de/para a memória global, incluindo cópias de/para o host da CPU e também solicitações de textura. O subsistema de cache L2 também implementa operações atômicas, usadas para gerenciar o acesso a dados que devem ser compartilhados entre blocos de threads ou até mesmo kernels.

### Memória global

Acessível por todos os threads, bem como pelo host (CPU). Alta latência (400-800 ciclos).

## Descompressão/compressão de vídeo

A tecnologia Nvidia NVENC ainda não estava disponível, mas foi introduzida o sucessor, Kepler.

## Chips Fermi

* GF100
* GF104
* GF106
* GF108
* GF110
* GF114
* GF116
* GF117
* GF119