# Advanced Vector Extensions

O Advanced Vector Extension (AVX), também conhecido como Sandy Bridge New Extensions, são extensões da arquitetura do conjunto de instruções x86 para microprocessadores da Intel e da AMD, propostas pela Intel em março de 2008 e primeiramente suportada pela Intel com o processador Sandy Bridge no início de 2011, e mais tarde então pela AMD, com o processador Bulldozer, lançado no final do mesmo ano. O AVX fornece novos recursos, instruções e um novo esquema de codificação.
O AVX2 expande a maioria dos comandos inteiros para 256 bits e apresenta operações de multiplicação acumulada fundidas (FMA). O AVX-512 expande o AVX para o suporte de 512 bits usando uma nova codificação de prefixo EVEX, proposta pela Intel em julho de 2013 e suportada pela primeira vez por ela, com o processador Knights Landing, lançado em 2016.

## AVX
### Características

O AVX utiliza dezesseis registradores YMM. Cada registrador YMM contém:
* Oito números de ponto flutuante de precisão única de 32 bits ou
* Quatro números de ponto flutuante de precisão dupla de 64 bits.
A largura do arquivo de registro SIMD é aumentada de 128 bits para 256 bits e renomeada de XMM0 – XMM7 para YMM0 – YMM7 (no modo x86-64, YMM0 – YMM15). Em processadores com o suporte a AVX, as instruções SSE (anteriormente operavam em registradores XMM de 128 bits) podem ser estendidas usando o prefixo VEX para operar nos 128 bits mais baixos dos registradores YMM.
Ele introduz um formato de instrução SIMD de três operandos, em que o registrador de destino é distinto dos dois operandos de origem. Por exemplo, uma instrução SSE usando a forma convencional de dois operandos a = a + b agora pode usar uma forma não destrutiva de três operandos c = a + b, preservando ambos os operandos fonte. O formato de três operandos do AVX é limitado às instruções com operandos SIMD (YMM) e não inclui instruções com registradores de propósito geral (por exemplo, EAX) (esse suporte aparecerá pela primeira vez no AVX2). O novo esquema de codificação VEX introduz um novo conjunto de prefixos de código que estende o espaço do opcode, permitindo que as instruções tenham mais de dois operandos e que os registradores vetoriais SIMD sejam maiores que 128 bits. O prefixo VEX também pode ser usado nas instruções herdadas do SSE, dando-lhes um formato de três operandos, e fazendo com que eles interajam mais eficientemente com as instruções do AVX, sem a necessidade de VZEROUPPER e ZEROALL.
As instruções do AVX suportam o SIMD de 128 bits e 256 bits. As versões de 128 bits podem ser úteis para melhorar o código antigo sem a necessidade de ampliar a vetorização, evitando assim a penalidade de ir do SSE para o AVX. Elas são mais rápidas em algumas implementações iniciais do AMD do AVX (este modo é conhecido como AVX-128).

### Novas Instruções

Estas instruções são adicionais às que são extensões de 256 bits das instruções SSE de 128 bits e a maioria é utilizável em operandos de 128 e 256 bits.
| Instrução | Descrição |
| VBROADCASTSS, VBROADCASTSD, VBROADCASTF128 | Copia um operando de memória de 32 bits, 64 bits ou 128 bits para todos os elementos de um registrador vetorial XMM ou YMM. |
| VINSERTF128 | Substitui a metade inferior ou a metade superior de um registrador YMM de 256 bits pelo valor de um operando de origem de 128 bits. A outra metade do destino não é alterada. |
| VEXTRACTF128 | Extrai a metade inferior ou a metade superior de um registrador YMM de 256 bits e copia o valor para um operando de destino de 128 bits. |
| VMASKMOVPS, VMASKMOVPD | Lê qualquer número de elementos de um operando de memória vetorial SIMD em um registrador de destino, deixando os elementos vetoriais restantes não lidos e definindo os elementos correspondentes no registrador de destino para zero. Grava qualquer número de elementos de um operando de registrador vetorial SIMD em um operando de memória de vetores, deixando os demais elementos do operando de memória inalterados. |
| VPERMILPS, VPERMILPD | Embaralha os elementos vetoriais de 32 bits ou 64 bits de um operando de entrada. Estas são instruções de 256 bits em pista, o que significa que elas operam em todos os 256 bits com dois shuffles de 128 bits separados, de modo que não podem ser reproduzidos aleatoriamente nas pistas de 128 bits. |
| VPERM2F128 | Embaralha os quatro elementos de vetor de 128 bits de dois operandos de fonte de 256 bits em um operando de destino de 256 bits, com uma constante imediata como seletor |
| VZEROALL | Define todos os registradores YMM para zero e marca-os como não utilizados. Usado ao alternar entre o uso de 128 bits e o uso de 256 bits. |
| VZEROUPPER | Ajusta a metade superior de todos os registradores YMM para zero. Utilizado ao alternar entre o uso de 128 bits e o uso de 256 bits. |

### CPUs com AVX

Intel:
* Processador Sandy Bridge (2011)
* Processador Sandy Bridge E (2011)
* Processador Ivy Bridge (2012)
* Processador Ivy Bridge E (2013)
* Processador Haswell (2013)
* Processador Haswell E (2014)
* Processador Broadwell (2014)
* Processador Broadwell E (2016)
* Processador Skylake (2015)
* Processador Kaby Lake (ULV mobile - 2016) (desktop/mobile - 2017)
* Processador Skylake-X (2017)
* Processador Coffee Lake (2017)
* Processador do Cannon Lake (microarquitetura), esperado para 2018
* Processador Cascade Lake, esperado em 2018
* Processador Ice Lake, esperado em 2018
Nem todas as CPUs das famílias listadas acima suportam o AVX. Geralmente, CPUs com a denominação "Core i3/i5/i7" as suportam, já as CPUs "Pentium" e "Celeron" não.
AMD:
* Processadores baseados em Jaguar e mais recentes
* Processadores baseados em Puma e mais recentes
* Processadores "Equipamentos Pesados"
** Processadores baseados em Bulldozer (2011)
** Processadores baseados em Piledriver (2012)
** Processadores baseados em Steamroller (2014)
** Processadores baseados em Excavator e mais novos (2015)
* Processadores baseados em Zen (2017)
* Processadores baseados em Zen+ (2018)
* Processadores baseados em Zen 2 (2019)

### Suporte ao sistema operacional

O AVX adiciona um novo estado de registro através do arquivo de registro YMM de 256 bits, portanto, é necessário suporte explícito ao sistema operacional para salvar e restaurar adequadamente os registros expandidos do AVX entre os comutadores de contexto. As seguintes versões dos sistemas operacionais suportam o AVX:
* Apple OS X: Suporte para AVX adicionado na atualização 10.6.8 (Snow Leopard), lançado em 23 de junho de 2011.
* O DragonFly BSD adicionou suporte no início de 2013.
* FreeBSD em um patch enviado em 21 de janeiro de 2012, incluído na versão 9.1.
* Linux: suportado desde a versão do kernel 2.6.30, lançado em 9 de junho de 2009.
* O OpenBSD adicionou suporte em 21 de março de 2015.
* Solaris 10 Update 10 e Solaris 11.
* Windows: suportado no Windows 7 SP1 e no Windows Server 2008 R2 SP1, Windows 8, Windows 10.

## AVX2
### Características

O Advanced Vector Extensions 2 (AVX2), também conhecido como Haswell New Instructions, é uma expansão do conjunto de instruções AVX introduzido na microarquitetura Haswell da Intel. O AVX2 faz as seguintes adições:
* Expansão da maioria das instruções SSE e AVX inteiras de vetores para 256 bits.
* Manipulação de bits de uso geral de três operandos e multiplicação.
* Reúne o suporte, permitindo que elementos vetoriais sejam carregados de locais de memória não contíguos.
* DWORD- e QWORD-
* Troca de vetores.
* Suporte de multiplexação acumulada de três operandos (FMA3).

### Novas Instruções

| Instrução | Descrição |
| VBROADCASTSS, VBROADCASTSD | Copia um operando de registrador de 32 bits ou 64 bits para todos os elementos de um registrador vetorial XMM ou YMM. Estas são versões de registradores das mesmas instruções no AVX1. No entanto, não existe uma versão de 128 bits, mas o mesmo efeito pode ser alcançado simplesmente usando o VINSERTF128. |
| VPBROADCASTB, VPBROADCASTW, VPBROADCASTD, VPBROADCASTQ | Copia um registrador inteiro de 8, 16, 32 ou 64 bits ou um operando de memória para todos os elementos de um registrador vetorial XMM ou YMM. |
| VBROADCASTI128 | Copia um operando de memória de 128 bits para todos os elementos de um registrador vetorial YMM. |
| VINSERTI128 | Substitui a metade inferior ou a metade superior de um registrador YMM de 256 bits pelo valor de um operando de origem de 128 bits. A outra metade do destino não é alterada. |
| VEXTRACTI128 | Extrai a metade inferior ou a metade superior de um registro YMM de 256 bits e copia o valor para um operando de destino de 128 bits. |
| VGATHERDPD, VGATHERQPD, VGATHERDPS, VGATHERQPS | Reúne valores de ponto flutuante de precisão simples ou dupla usando índices e escala de 32 ou 64 bits. |
| VPGATHERDD, VPGATHERDQ, VPGATHERQD, VPGATHERQQ | Reúne valores inteiros de 32 ou 64 bits usando índices e escala de 32 ou 64 bits. |
| VPMASKMOVD, VPMASKMOVQ | Lê qualquer número de elementos de um operando de memória vetorial SIMD em um registrador de destino, deixando os elementos vetoriais restantes não lidos e definindo os elementos correspondentes no registrador de destino para zero. Grava qualquer número de elementos de um operando de registrador vetorial SIMD em um operando de memória de vetores, deixando os demais elementos do operando de memória inalterados. |
| VPERMPS, VPERMD | Embaralha os oito elementos vetoriais de 32 bits de um operando fonte de 256 bits em um operando de destino de 256 bits, com um registrador ou operando memória como seletor. |
| VPERMPD, VPERMQ | Embaralha os quatro elementos de vetor de 64 bits de um operando de fonte de 256 bits em um operando de destino de 256 bits, com um operando de registro ou memória como seletor. |
| VPERM2I128 | Embaralha os quatro elementos de vetor de 128 bits de dois operandos de fonte de 256 bits em um operando de destino de 256 bits, com uma constante imediata como seletor. |
| VPBLENDD | Versão imediata da palavra dupla das instruções PBLEND do SSE4. |
| VPSLLVD, VPSLLVQ | Troca lógica. Permite deslocamentos variáveis em que cada elemento é deslocado de acordo com a entrada compactada. |
| VPSRLVD, VPSRLVQ | Troca lógica. Permite deslocamentos variáveis em que cada elemento é deslocado de acordo com a entrada compactada. |
| VPSRAVD | Troca lógica aritmética. Permite deslocamentos variáveis em que cada elemento é deslocado de acordo com a entrada compactada. |

### CPUs com AVX2

Intel:
* Processador Haswell (2013)
* Processador Haswell E (2014)
* Processador Broadwell (2014)
* Processador Broadwell E (2016)
* Processador Skylake (2015)
* Processador Kaby Lake, (ULV mobile - 2016) (desktop/mobile - 2017)
* Processador Skylake-X (2017)
* Processador Coffee Lake (2017)
* Processador Cannon Lake, esperado em 2018
* Processador Cascade Lake, esperado em 2018
* Processador Ice Lake, esperado em 2018
AMD:
* Processador Excavator e mais novos (2015)
* Processador Zen (2017)

## AVX-512

O AVX-512 são extensões de 512 bits para as instruções SIMD de extensões de vetor avançadas de 256 bits para a arquitetura de conjunto de instruções x86 propostas pela Intel em julho de 2013 e programadas para serem suportadas em 2015 com o processador Knights Landing da Intel.
A instrução AVX-512 é codificada com o novo prefixo EVEX. Ele permite 4 operandos, 7 novos registros opmask de 64 bits, modo de memória escalar com transmissão automática, controle de arredondamento explícito e modo de endereçamento de memória de deslocamento comprimido. A largura do arquivo de registro é aumentada para 512 bits e a contagem total de registros aumentada para 32 (registra ZMM0-ZMM31) no modo x86-64.

### CPUs com AVX-512

* Processadores Knights Landing (2016)
* Processadores Knights Mill (2017)
* Processadores Skylake-SP, Skylake-X (2017)
* Processadores Cannon Lake (2018)
* Processadores Ice Lake (2019)

## Aplicações

O AVX é adequado para cálculos de ponto flutuante intensivo em aplicações multimídia, científicas e financeiras (o AVX2 adiciona suporte para operações inteiras).
Aumenta o paralelismo e o rendimento em cálculos SIMD de ponto flutuante, reduz a carga do registrador devido às instruções não destrutivas e melhora o desempenho do software Linux RAID (AVX2).

### Softwares

* Blender - usa o AVX2 nos ciclos do mecanismo de renderização.
* OpenSSL - usa funções criptográficas otimizadas para AVX e AVX2 desde a versão 1.0.2.
* Prime95 / MPrime, software usado para o GIMPS - começou a usar as instruções AVX desde a versão 27.x.
* O dnetc, o software usado pela distributed.net, tem um núcleo AVX2 disponível para seu projeto RC5 e lançará em breve um para seu projeto OGR-28.
* Einstein @ Home - usa o AVX em alguns de seus aplicativos distribuídos que buscam ondas gravitacionais.
* RPCS3, emulador de código aberto para o PlayStation 3 - usa as instruções AVX2 e AVX-512 para emular jogos PS3.
* Network Device Interface, um protocolo de vídeo / áudio IP desenvolvido pela NewTek para produção de transmissão ao vivo - usa AVX e AVX2 para aumentar o desempenho.