Escrevendo um OS em Rust

Philipp Oppermann's blog

Desabilitando SIMD

Instruções Single Instruction Multiple Data (SIMD) são capazes de realizar uma operação (por exemplo, adição) simultaneamente em múltiplas palavras de dados, o que pode acelerar programas significativamente. A arquitetura x86_64 suporta vários padrões SIMD:

  • MMX: O conjunto de instruções Multi Media Extension foi introduzido em 1997 e define oito registradores de 64 bits chamados mm0 até mm7. Esses registradores são apenas aliases para os registradores da unidade de ponto flutuante x87.
  • SSE: O conjunto de instruções Streaming SIMD Extensions foi introduzido em 1999. Em vez de reutilizar os registradores de ponto flutuante, ele adiciona um conjunto de registradores completamente novo. Os dezesseis novos registradores são chamados xmm0 até xmm15 e têm 128 bits cada.
  • AVX: As Advanced Vector Extensions são extensões que aumentam ainda mais o tamanho dos registradores multimídia. Os novos registradores são chamados ymm0 até ymm15 e têm 256 bits cada. Eles estendem os registradores xmm, então por exemplo xmm0 é a metade inferior de ymm0.

Ao usar tais padrões SIMD, programas frequentemente podem acelerar significativamente. Bons compiladores são capazes de transformar loops normais em tal código SIMD automaticamente através de um processo chamado auto-vetorização.

No entanto, os grandes registradores SIMD levam a problemas em kernels de SO. A razão é que o kernel tem que fazer backup de todos os registradores que usa para a memória em cada interrupção de hardware, porque eles precisam ter seus valores originais quando o programa interrompido continua. Então, se o kernel usa registradores SIMD, ele tem que fazer backup de muito mais dados (512-1600 bytes), o que diminui notavelmente o desempenho. Para evitar esta perda de desempenho, queremos desabilitar os recursos sse e mmx (o recurso avx é desabilitado por padrão).

Podemos fazer isso através do campo features na nossa especificação de alvo. Para desabilitar os recursos mmx e sse, nós os adicionamos prefixados com um menos:

"features": "-mmx,-sse"

Ponto Flutuante

Infelizmente para nós, a arquitetura x86_64 usa registradores SSE para operações de ponto flutuante. Assim, todo uso de ponto flutuante com SSE desabilitado causa um erro no LLVM. O problema é que a biblioteca core do Rust já usa floats (por exemplo, ela implementa traits para f32 e f64), então evitar floats no nosso kernel não é suficiente.

Felizmente, o LLVM tem suporte para um recurso soft-float que emula todas as operações de ponto flutuante através de funções de software baseadas em inteiros normais. Isso torna possível usar floats no nosso kernel sem SSE; será apenas um pouco mais lento.

Para ativar o recurso soft-float para o nosso kernel, nós o adicionamos à linha features na nossa especificação de alvo, prefixado com um mais:

"features": "-mmx,-sse,+soft-float"

Comments

Teve algum problema, quer deixar um feedback ou discutir mais ideias? Fique à vontade para deixar um comentário aqui! Por favor, use o inglês e siga o código de conduta do Rust. Este tópico de comentários está diretamente vinculado a uma discussão no GitHub, então você também pode comentar lá se preferir.

Instead of authenticating the giscus application, you can also comment directly on GitHub.