SIMD e Extensões de código de CPU no Linux
O cálculo com ponto flutuante sempre foi o nó górdio para os sistemas operacionais. Sua importância se revela na própria unidade de medida de velocidade de processamento: FLOPS (
FLoating-points Operations Per Second) ou número de operações de ponto flutuante por segundo. 1997 foi um ano decisivo para os sistemas operacionais. Os fabricantes de chips para CPU disputavam nas raias da velocidade de processamento e implementavam registros de 64 e 128 bits para cálculos com ponto flutuante (
Floating Point). Os 3 principais fabricantes (Intel, AMD e Cyrix) disputavam ombro a ombro no ranking de velocidade.
A AMD disparou na frente com o seu processador K6-2 e, posteriormente o Athlon, que utilizavam a tecnologia apelidada de
3DNow, além do suporte a MMX, memória cache secundária e
Accelerated Graphics Port (AGP). A tecnologia 3DNow permitia o cálculo com números de ponto flutuante em registros de 64/80 bits, com instruções específicas para o processador que permitiam a operação no mesmo registro.
A resposta da Intel foi rápida. Quando a Intel lançou os
Pentium III foram criadas 70 novas instruções de código e 8 registros para estes processadores, com a finalidade de incrementar o desempenho do processamento de ponto flutuante (
Floating-Point Unity - FPU). Estas instruções extendidas do conjunto de instruções do processador foi denominada de
Streaming SIMD Extensions (SSE). A tecnologia SSE implementava os registradores XMM de 128 bits. A vantagem da tecnologia da Intel é que a operação podia ser feita com até 4 números no mesmo registro.
As extensões foram sendo otimizadas e os processadores passaram a disponibilizar 8 registros de 128 bits (
XMM0 ... XMM7 nos processadores com suporte a SSE) e depois 16 registros de 128 bits (
XMM0 ... XMM15 nas CPUs com suporte a SSE2 em diante). Atualmente, o suporte é de até 16 registros de 256 bits (
YMM0 ... YMM15 nas CPUs com suporte a
AVX). Nas CPUs com suporte a AVX os bits de 0-127 dos registros YMM0 ... YMM15 funcionam como registros XMM.
A tecnologia AVX (
Advanced Vector Extensions) implementa novas instruções do processador para operar sobre os registros YMM, usando até 3 endereços de fonte de dados e um endereçamento de destino de dados em uma única instrução do tipo
Single Instruction Multiple Data (SIMD).
Em um sistema multitarefa preemptivo como o Linux o uso destas extensões de SIMD requer uma habilidade adicional no controle dos registradores. Por isto o
kernel do SO tem que estar preparado para lidar com registros extendidos. Por exemplo, quando o sistema passa o controle de um processo para outro, os registros SIMD do processo anterior têm que ser salvos e o novo conjunto de registros SIMD do processo que entra para rodar é carregado no processador. O SO tem que estar pronto para lidar com estes registros extendidos e gerenciá-los apropriadamente.
No
kernel do linux (3.x) o suporte a este tipo de processamento é fundamental para a paralelização de algorítmos e o suporte a SMP (
Symetric MultiProcessing) em processadores dualcore, quadricore, i5, i7 etc. e isto depende do suporte no kernel a instruções extendidas SSE / SSE5 e AVX do processador.
Para ver o suporte do processador a estas extensões, use o comando:
cat /proc/cpuinfo |grep flags
O comando retorna o campo "flags" de cada núcleo ou processador.
Allternativamente, pode-se usar o nome do flag da extensão. Por exemplo:
cat /proc/cpuinfo |grep sse
Normalmente, os sistemas operacionais mais modernos já são configurados para o suporte às extensões da CPU. No kernel, fica tudo definido nos arquivos:
/src/linux-.../arch/x86/include/asm/processor.h
/src/linux-.../arch/x86/include/asm/sigcontext.h
/src/linux-.../arch/x86/include/asm/xsave.h
/src/linux-.../arch/x86/kernel/cpu/common.c
/src/linux-.../arch/x86/kernel/xsave.c
O processamento paralelo é vantajoso para cálculos matemáticos de alto desempenho tanto para processamento em computação científica como em processamento de sinais de áudio e imagem para execução, em tempo real, de aplicativos multimedia. No entanto, o rendimento é dependente da fração do programa que pode ser paralelizada e do número de núcleos envolvidos no algorítmo em paralelo. A relação é de
`V=frac{n}{(n-1)f + 1}`
onde V é a velocidade de processamento, n é o número de processos paralelos e f é um fator de paralelismo (veja
lei de Amdahl).
Normalmente, programas que utilizam as bibliotecas do BLAS (
Basic Linear Algebra Subprograms), LAPACK (
Linear Algebra PACKage) e ATLAS (
Automatically Tuned Linear Algebra Software) podem usar o processamento vetorial avançado provido por estas extensões da CPU.
Além disso, existem outras aplicações que podem usar estas extensões para processamento, tais como: funções transformadas FFT, Wavelet e outras aplicações para sistemas lineares; algoritmos de RNG (
Random Number Generator) para funções de distribuição estatística; aplicações para criptografia; e, ainda, rotinas numéricas em FORTRAN e C/C++ de software como (Octave, Scilab, Matlab e Matematica).
...
Dave Bowman:
Yes, I'd like to hear it, HAL. Sing it for me.
HAL:
It's called "Daisy."
[
sings while slowing down]
HAL:
Daisy, Daisy, give me your answer do. I'm half crazy all for the love of
you. It won't be a stylish marriage, I can't afford a carriage. But
you'll look sweet upon the seat of a bicycle built for two.
Referências:
http://pt.scribd.com/dbrunecz/d/57793168-Optimizing-Assembly
http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/intref_cls/common/intref_avx_details.htm
http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
http://en.wikipedia.org/wiki/Advanced_Vector_Extensions