Como Projetar Chips de GPU
Chapter 10 Reliability and Fault Tolerance Gpu Design

Capítulo 10: Confiabilidade e Tolerância a Falhas no Design de GPUs

À medida que as GPUs se tornam cada vez mais prevalentes em aplicações críticas para a segurança, como veículos autônomos, robótica e dispositivos médicos, garantir sua confiabilidade e tolerância a falhas se torna fundamental. As GPUs são suscetíveis a vários tipos de falhas e erros que podem levar a falhas no sistema, corrupção de dados ou resultados incorretos. Neste capítulo, exploraremos os tipos de falhas e erros em GPUs, esquemas de detecção e correção de erros, mecanismos de checkpoint e recuperação, e princípios de design para confiabilidade e resiliência.

Tipos de Falhas e Erros em GPUs

As falhas e erros em GPUs podem ser classificados em várias categorias com base em sua origem, duração e impacto no sistema. Entender esses diferentes tipos de falhas e erros é crucial para desenvolver estratégias de mitigação eficazes.

Erros Transitórios

Os erros transitórios, também conhecidos como falhas transitórias, são erros temporários causados por fatores externos, como raios cósmicos, partículas alfa ou interferência eletromagnética. Esses erros não causam danos permanentes ao hardware e podem ser corrigidos reescrevendo os dados afetados ou reiniciando a operação afetada.

Os erros transitórios podem se manifestar em várias partes da GPU, como:

  1. Flip-flops e latches: Um evento de perturbação única (SEU) pode fazer com que o estado de um flip-flop ou latch mude, levando a dados ou fluxo de controle incorretos.

  2. Células SRAM: Erros transitórios em células SRAM, como as usadas em caches e registradores, podem corromper os dados armazenados.

  3. Células DRAM: Embora menos comuns que os erros transitórios em SRAM, as células DRAM também podem sofrer inversões de bits devido a fatores externos.

A Figura 10.1 ilustra o impacto de um erro transitório em um flip-flop.

           Raio Cósmico
               |
               |
               v
        +------------+
        |            |
D ----->|  Flip-Flop |----> Q
        |            |
        +------------+
               |
               |
               v
```Erro Suave

Figura 10.1: Erro suave causado por um raio cósmico atingindo um flip-flop.

Erros Permanentes

Erros permanentes, também conhecidos como falhas permanentes, são defeitos físicos irreversíveis no hardware que persistem ao longo do tempo. Esses erros podem ser causados por defeitos de fabricação, desgaste ou danos físicos ao dispositivo.

Exemplos de erros permanentes em GPUs incluem:

  1. Falhas de valor fixo: Um sinal ou elemento de armazenamento está permanentemente preso a um valor lógico '0' ou '1', independentemente da entrada.

  2. Falhas de curto-circuito: Duas ou mais linhas de sinal estão acidentalmente conectadas, causando um curto-circuito.

  3. Falhas de circuito aberto: Uma linha de sinal está acidentalmente desconectada, causando um valor flutuante ou indeterminado.

  4. Falhas de atraso: Um sinal leva mais tempo do que o esperado para se propagar por um caminho, levando a violações de tempo.

A Figura 10.2 mostra um exemplo de uma falha de valor fixo em um portão lógico.

        Falha de Valor Fixo em 0
               |
               |
               v
           +---+
        -->| & |-->
           |   |
        -->|   |
           +---+

Figura 10.2: Falha de valor fixo em 0 em um portão AND.

Erros Intermitentes

Erros intermitentes são falhas que ocorrem de forma esporádica e são difíceis de reproduzir consistentemente. Esses erros podem ser causados por vários fatores, como:

  1. Hardware marginal: Componentes que estão operando próximo aos seus limites especificados, tornando-os mais suscetíveis a fatores ambientais ou envelhecimento.

  2. Fatores ambientais: Flutuações de temperatura, variações de tensão ou interferência eletromagnética podem desencadear erros intermitentes.

  3. Efeitos de envelhecimento: À medida que o dispositivo envelhece, certos componentes podem se tornar mais propensos a falhas intermitentes devido ao desgaste ou à degradação.

Erros intermitentes representam um desafio significativo para a detecção e correção de erros, pois podem não ser capturados por técnicas de teste ou monitoramento tradicionais.

Corrupção de Dados Silenciosa

A corrupção de dados silenciosa (SDC) refere-se a erros que corrompem os dados semAqui está a tradução em português deste arquivo markdown. Para o código, não traduzi o código, apenas os comentários.

Detecção de Erros Silenciosos (SDC) em GPUs

Erros Silenciosos de Dados (SDC) são erros que ocorrem no processamento de dados em um sistema de computação, mas não são detectados pelo hardware ou software. O SDC pode levar a resultados incorretos ou falhas no sistema que podem passar despercebidas por um longo período.

Exemplos de SDC em GPUs incluem:

  1. Erros aritméticos: Falhas em unidades aritméticas, como somadores ou multiplicadores, podem produzir resultados incorretos sem gerar nenhum sinal de erro.

  2. Erros de memória: Erros suaves ou falhas permanentes em células de memória podem corromper dados sem serem detectados pelos mecanismos de verificação de erros.

  3. Erros de fluxo de controle: Falhas na lógica de controle ou decodificadores de instrução podem fazer o programa desviar do caminho de execução pretendido sem disparar exceções.

O SDC é particularmente perigoso porque pode se propagar pelo sistema e afetar o resultado final sem nenhum sintoma visível. Detectar e mitigar o SDC requer uma combinação de técnicas de hardware e software.

Esquemas de Detecção e Correção de Erros

Para mitigar o impacto de falhas e erros em GPUs, vários esquemas de detecção e correção de erros foram desenvolvidos. Esses esquemas visam identificar a presença de erros e, em alguns casos, corrigi-los para garantir o funcionamento correto do sistema.

Verificação de Paridade

A verificação de paridade é uma técnica simples de detecção de erros que adiciona um bit extra (o bit de paridade) a cada palavra de dados para tornar o número total de bits '1' par (paridade par) ou ímpar (paridade ímpar). Verificando a paridade da palavra de dados, é possível detectar erros de bit único.

A Figura 10.3 ilustra um exemplo de verificação de paridade par.

    Palavra de Dados: 1011010
    Bit de Paridade:      1
    Transmitido: 10110101

    Recebido:   10110111
    Bit de Paridade:      0
    Erro Detectado!

Figura 10.3: Verificação de paridade par para detecção de erros.

A verificação de paridade pode ser aplicada a vários componentes da GPU, como registradores, caches e interfaces de memória. No entanto, a verificação de paridade só pode detectar números ímpares de erros de bit e não pode corrigir os erros.

Códigos de Correção de Erros (ECC)

Os Códigos de Correção de Erros (ECC) sãoAqui está a tradução em português do arquivo Markdown, com os comentários traduzidos, mas o código não traduzido:

Esquemas mais avançados de detecção e correção de erros que não apenas podem detectar erros, mas também corrigi-los. ECC funciona adicionando bits redundantes à palavra de dados, o que permite que o receptor identifique e corrija um número limitado de erros de bits.

Um esquema comum de ECC é o código de Correção de Erro Único, Detecção de Erro Duplo (SECDED), que pode corrigir erros de bits únicos e detectar erros de bits duplos. Os códigos SECDED são frequentemente usados em sistemas de memória, como DRAM e caches, para proteger contra erros suaves.

A Figura 10.4 mostra um exemplo de um código SECDED.

    Palavra de Dados: 1011010
    Bits de ECC:    01101
    Transmitido: 101101001101

    Recebido:   101101011101
                       ^
                       |
                   Erro de Bit

    Corrigido:  101101001101

Figura 10.4: Código SECDED para correção e detecção de erros.

Outros esquemas de ECC, como os códigos Bose-Chaudhuri-Hocquenghem (BCH) e Reed-Solomon, podem corrigir múltiplos erros de bits com o custo de maior redundância e complexidade.

Execução Redundante

A execução redundante é uma técnica que realiza o mesmo cálculo várias vezes, seja no mesmo hardware ou em diferentes unidades de hardware, e compara os resultados para detectar erros. Se os resultados não corresponderem, um erro é detectado e o sistema pode tomar as medidas apropriadas, como repetir o cálculo ou iniciar um processo de recuperação.

A execução redundante pode ser implementada em vários níveis na GPU:

  1. Redundância a nível de instrução: Cada instrução é executada várias vezes e os resultados são comparados antes de serem confirmados no arquivo de registros ou na memória.

  2. Redundância a nível de thread: Várias threads executam o mesmo cálculo e seus resultados são comparados para detectar erros.

  3. Redundância a nível de kernel: Todo o kernel é executado várias vezes e as saídas finais são comparadas para detectar erros.

A Figura 10.5 ilustra a redundância a nível de thread em uma GPU.

    Thread 0   Thread 1   Thread 2   Thread 3
```Aqui está a tradução em português do arquivo Markdown, com os comentários traduzidos, mas o código não traduzido:

|          |          |          |
       v          v          v          v
    +-------+  +-------+  +-------+  +-------+
    | Comp. |  | Comp. |  | Comp. |  | Comp. |
    +-------+  +-------+  +-------+  +-------+
       |          |          |          |
       v          v          v          v
    +------------+------------+------------+
    |          Comparador                 |
    +------------+------------+------------+
                 |
                 v
            Detecção de Erros

Figura 10.5: Redundância a nível de thread para detecção de erros.

A execução redundante pode detectar uma ampla gama de erros, incluindo erros suaves, falhas permanentes e SDC. No entanto, isso vem com o custo de maior tempo de execução e consumo de energia.

Temporizadores de Watchdog

Os temporizadores de watchdog são mecanismos de hardware ou software que monitoram a execução da GPU e detectam se o sistema se torna não responsivo ou não consegue concluir uma tarefa dentro de um limite de tempo especificado. Se o temporizador de watchdog expirar, isso indica um erro, e o sistema pode iniciar um processo de recuperação, como redefinir a GPU ou reiniciar a operação afetada.

Os temporizadores de watchdog podem ser implementados em vários níveis na GPU:

  1. Watchdog a nível de kernel: Monitora o tempo de execução de cada kernel e detecta se um kernel não consegue concluir dentro de um limite de tempo especificado.

  2. Watchdog a nível de thread: Monitora o tempo de execução de cada thread e detecta se uma thread não consegue concluir dentro de um limite de tempo especificado.

Mecanismos de Checkpoint e Recuperação

Os mecanismos de checkpoint e recuperação são usados para salvar o estado de uma aplicação da GPU em intervalos regulares e restaurar o estado em caso de falha. Ao salvar periodicamente o estado da aplicação, o sistema pode se recuperar de falhas sem ter que reiniciar todo o cálculo desde o início.

Os mecanismos de checkpoint e recuperação podem ser implementados em diferentes níveis na GPU:

  1. Checkpoint a nível de aplicação: A própria aplicação é responsável por salvar e restaurar seu próprio estado.

1. **Checkpointing a nível de aplicação**: A própria aplicação é responsável por salvar seu estado em intervalos regulares. Isso pode ser feito salvando explicitamente o conteúdo da memória e dos registradores em um arquivo de checkpoint.

2. **Checkpointing a nível de sistema**: O sistema de tempo de execução ou o driver da GPU é responsável por salvar o estado da aplicação. Isso pode ser feito de forma transparente para a aplicação, sem exigir modificações no código da aplicação.

3. **Checkpointing a nível de hardware**: O próprio hardware da GPU fornece suporte para salvar e restaurar o estado da aplicação. Isso pode ser feito usando mecanismos de hardware dedicados, como memória não volátil ou registradores de propósito especial.

A Figura 10.8 ilustra um processo típico de checkpoint e recuperação.

Execução Normal | | v Checkpoint | | v Execução Normal | | v Falha | | v Restaurar | | v Execução Normal

Figura 10.8: Processo de checkpoint e recuperação.

Durante a execução normal, o sistema salva periodicamente o estado da aplicação em um checkpoint. Se ocorrer uma falha, o sistema restaura o estado do último checkpoint e retoma a execução a partir desse ponto.

Os mecanismos de checkpoint e recuperação podem ajudar a melhorar a confiabilidade e a resiliência de aplicações GPU, especialmente para cálculos de longa duração. No entanto, eles também introduzem overhead em termos de espaço de armazenamento e tempo de execução, pois salvar e restaurar o estado requer recursos adicionais.

### Projetando para Confiabilidade e Resiliência

Projetar GPUs para confiabilidade e resiliência envolve uma combinação de técnicas de hardware e software. Alguns princípios e técnicas de design importantes incluem:

1. **Detecção e correção de erros**: Incorporar mecanismos de detecção e correção de erros, como ECC e verificação de paridade, em vários níveis da GPU, incluindo memórias, caches e interconexões.

2. **Redundância**: Usar redundância para aumentar a tolerância a falhas, como replicação de componentes críticos ou execução redundante de tarefas.Componentes de hardware de formigas, como núcleos de reserva ou módulos de memória, para fornecer tolerância a falhas e permitir a degradação gradual na presença de falhas.

3. **Checkpoint e recuperação**: Implementação de mecanismos de checkpoint e recuperação para salvar o estado da aplicação e permitir a recuperação de falhas.

4. **Contenção de falhas**: Projetar a arquitetura da GPU para limitar a propagação de erros e evitar que as falhas se espalhem por todo o sistema. Isso pode ser alcançado por meio de técnicas como particionamento, isolamento e barreiras de contenção de erros.

5. **Resiliência de software**: Desenvolver técnicas de software, como tolerância a falhas baseada em algoritmos (ABFT), que permitam que as aplicações detectem e se recuperem de erros por meio de redundância e verificação no nível de software.

6. **Agendamento consciente da confiabilidade**: Adaptar o agendamento de tarefas e recursos na GPU para levar em conta as características de confiabilidade de diferentes componentes e otimizar tanto o desempenho quanto a confiabilidade.

Exemplo: Agendamento consciente da confiabilidade em uma GPU

Considere uma GPU com vários núcleos, onde alguns núcleos são conhecidos por serem mais propensos a erros do que outros. Um agendador consciente da confiabilidade pode atribuir tarefas críticas ou tarefas com altos requisitos de confiabilidade aos núcleos mais confiáveis, enquanto atribui tarefas menos críticas aos núcleos menos confiáveis.

A Figura 10.9 ilustra uma abordagem de agendamento consciente da confiabilidade.

Fila de Tarefas +-------+ | Tarefa1| | Tarefa2| | Tarefa3| | Tarefa4| +-------+ | | v Agendador Consciente da Confiabilidade | | v +--------+--------+ | Núcleo 1| Núcleo 2| | (AR) | (BR) | +--------+--------+ | Tarefa1| Tarefa3 | | Tarefa2| Tarefa4 | +--------+--------+

Figura 10.9: Agendamento consciente da confiabilidade em uma GPU (AR: Alta Confiabilidade, BR: Baixa Confiabilidade).

Neste exemplo, o agendador atribui a Tarefa1 e a Tarefa2, que têm altos requisitos de confiabilidade, ao Núcleo 1, que é conhecido por ser maisAqui está a tradução em português do arquivo markdown, com os comentários do código traduzidos:

## Conclusão

A confiabilidade e a tolerância a falhas são aspectos críticos do design e operação de GPUs, especialmente à medida que as GPUs são cada vez mais utilizadas em aplicações de segurança crítica. Entender os tipos de falhas e erros que podem ocorrer em GPUs, bem como as técnicas para detectar, corrigir e recuperar-se dessas falhas, é essencial para projetar sistemas de GPU confiáveis e resilientes.

Esquemas de detecção e correção de erros, como ECC e verificação de paridade, desempenham um papel crucial na identificação e mitigação de erros suaves e falhas graves em vários componentes da GPU. Mecanismos de checkpoint e recuperação permitem que o sistema salve o estado da aplicação e se recupere de falhas, melhorando a resiliência geral do sistema.

Projetar GPUs para confiabilidade e resiliência envolve uma abordagem holística que combina técnicas de hardware e software. Redundância, contenção de falhas, resiliência de software e escalonamento ciente da confiabilidade são algumas das principais técnicas que podem ser empregadas para melhorar a confiabilidade e a tolerância a falhas das GPUs.

À medida que as GPUs continuam a evoluir e encontram novas aplicações em domínios como veículos autônomos, robótica e saúde, garantir sua confiabilidade e resiliência se tornará cada vez mais importante. Técnicas inovadoras para detecção e correção de erros, checkpoint e recuperação, e gerenciamento de recursos ciente da confiabilidade serão essenciais para habilitar a próxima geração de GPUs confiáveis e tolerantes a falhas.