SIMD empacotado

Operações paralelas em quatro bytes ou duas meias palavras de registos RV32.

TLDR

Perguntar sobre esta página

ChatGPTClaudePerplexityGrokGeminiCopiar e abrirDeepSeekCopiar e abrir

ADD8 soma quatro pares de bytes com uma instrução. Cada registo RV32 é dividido em quatro vias de 8 bits; ADD16 divide-o em duas de 16 bits. SIMD significa uma instrução aplicada a múltiplos dados.

Este modelo empacotado usa os registos inteiros normais e as mnemónicas históricas dos materiais FEUP. Não usa o banco vetorial v0…v31 da extensão RVV. A largura de cada via determina a interpretação, o overflow e a forma de guardar os resultados.

Vias e interpretação

r.B[0] é o byte baixo, bits 7 a 0; r.B[3] é o alto. r.H[0] é a meia palavra baixa, bits 15 a 0. A numeração das vias não depende da ordem em que escreves os dígitos hexadecimais.

Flynn distingue SISD, um fluxo de instruções/dados; SIMD, um fluxo de instruções para vários dados; MISD, vários fluxos de instruções sobre um de dados; MIMD, vários fluxos de ambos. Vários núcleos independentes são MIMD; cada núcleo pode também executar SIMD.

Soma, subtração e overflow

ADD8 soma separadamente quatro pares de bytes; ADD16, dois pares de 16 bits. SUB8/SUB16 fazem a diferença. Cada via mantém os seus bits baixos, sem transportar carry para a via vizinha.

Com vias baixas [250,2,3,4] + [10,20,30,40], ADD8 produz [4,22,33,44]. Uma soma escalar dos registos inteiros propagaria o carry do 250+10, dando 23 na segunda via.

Sem sinal, 4 é o resultado modular 260 mod 256. Com sinal, a mesma operação usa padrões em complemento para dois; ADD8 não satura no máximo 127. Saturação e descarte de bits são comportamentos diferentes.

Operações diretas e cruzadas

InstruçãoVia alta H1Via baixa H0
STAS16a.H1+b.H1a.H0−b.H0
STSA16a.H1−b.H1a.H0+b.H0
CRAS16a.H1+b.H0a.H0−b.H1
CRSA16a.H1−b.H0a.H0+b.H1

Os resultados são reduzidos a 16 bits por via. Escreve as duas equações antes de calcular um valor hexadecimal, porque trocar H0/H1 muda a operação.

Comparações e deslocamentos

Com bytes dados pela ordem [B0,B1,B2,B3], um deslocamento aritmético de 1 produz:

ViaAntes, hexadecimalInteiro com sinalDepois, com sinalPadrão resultante
B00x81−127−640xC0
B10x02210x01
B20xFF−1−10xFF
B30x101680x08

Cada via replica o seu próprio sinal. Um shift escalar da palavra 0x10FF0281 dá 0x087F8140, diferente da palavra empacotada 0x08FF01C0. Na operação escalar, bits atravessam fronteiras entre bytes.

Para mínimos com sinal, compara via a via com a interpretação escolhida: a=[10,−20,30,−40] e b=[5,−10,40,−30] dão [5,−20,30,−40]. O padrão 0xF0 contra 10 torna a escolha visível: −16 é menor que 10, mas 240 é maior.

CMPEQ8/16 testa igualdade. SCMPLT/SCMPLE interpreta operandos com sinal; UCMPLT/UCMPLE, sem sinal. Uma comparação verdadeira produz todos os bits 1 da via, isto é 0xFF ou 0xFFFF; falsa produz zero.

O padrão byte 0xF0 representa −16 com sinal e 240 sem sinal. Compará-lo com 10 dá verdadeiro em SCMPLT8 e falso em UCMPLT8.

Deslocamentos lógicos introduzem zeros; aritméticos replicam o sinal em cada via. O número de posições usa 3 bits para vias de 8 bits e 4 para vias de 16 bits neste modelo. Não uses um shift escalar do registo inteiro para imitar um shift por via: misturaria bits entre parcelas.

Multiplicação e pares de registos

SMUL16 calcula H0×H0 e H1×H1 com sinal. Cada produto de duas meias palavras ocupa 32 bits, por isso os dois resultados exigem um par de registos. SMULX16 cruza H0×H1 e H1×H0; as variantes UMUL interpretam sem sinal.

Para a=[−2,3] e b=[4,5], na ordem H0,H1:

OperaçãoRegisto baixo do parRegisto alto do par
SMUL16(−2)×4=−8(−2)\times4=−83×5=153\times5=15
SMULX16(−2)×5=−10(−2)\times5=−103×4=123\times4=12

O par físico usa um registo de índice par e o seguinte, como t3/t4, isto é, x28/x29. Na notação de par d, os destinos são x[2d] e x[2d+1]. O registo baixo contém um produto completo, não dois produtos de 16 bits. Para voltar a empacotar, extrai a parte pretendida de cada produto e verifica se cabe.

SMUL8 produz quatro produtos de 16 bits: B0 e B1 ficam no registo baixo, B2 e B3 no alto. KMDA, por sua vez, soma os dois produtos de meias palavras e dá um parcial de 32 bits.

Se ambos os operandos de KMDA forem 0x80008000, os dois produtos valem 2302^{30} e a soma matemática é 2312^{31}. KMDA satura em 0x7FFFFFFF, em vez de devolver essa soma exata. Um acumulador largo usado depois não recupera a unidade já perdida.

Empacotar, trocar e estender

InstruçãoResultado (H1,H0)
PKBB16(a.H0,b.H0)
PKTT16(a.H1,b.H1)
PKBT16(a.H0,b.H1)
PKTB16(a.H1,b.H0)
SWAP16(a.H0,a.H1)

SWAP8 troca bytes adjacentes em cada meia palavra. SUNPKD estende bytes escolhidos com sinal para meias palavras; ZUNPKD preenche com zeros. O sufixo da variante identifica os bytes selecionados. Por exemplo, SUNPKD820 coloca B2 em H1 e B0 em H0, estendendo cada sinal. Para 0x12FE34F0, dá 0xFFFEFFF0; ZUNPKD820 dá 0x00FE00F0. Não é um shift do registo inteiro, porque cada byte passa a ter 16 bits.

Voltando à soma inicial, as vias B0 a B3 dão [4,22,33,44], palavra 0x2C211604. A soma escalar dá 0x2C211704, pois o carry de B0 entra em B1. Para a comparação com sinal dos bytes [0xF0,10,127,0x80] com 10, as máscaras são [0xFF,0,0,0xFF]. O resultado é uma máscara por via, não quatro contagens escalares.

Exercícios

Impedir carry entre vias

ADD8 soma vias baixas [250,2,3,4] e [10,20,30,40]. Qual é B1 do resultado?

Pista
Cada byte é uma soma independente.
Solução

B1=22; B0=260 mod 256=4, ou seja, uma soma escalar produziria B1=23.

Erros frequentes

Propagar o carry para a via seguinte.
Voltar à explicação
Escolher uma comparação

Compara o byte 0xF0 com 10. Quais são as máscaras assinada e sem sinal?

A tua resposta

Pista
O padrão de bits tem duas interpretações.
Solução

SCMPLT8 dá 0xFF; UCMPLT8 dá 0x00. Máscara não é o inteiro 1.

  • SCMPLT8 produz 0xFF; UCMPLT8 produz 0. 0xF0 é −16 com sinal e 240 sem sinal.
  • Ambas produzem 0xFF. 240 não é menor que 10 sem sinal.
  • Ambas produzem 1. A máscara verdadeira tem todos os bits 1 da via.

Erros frequentes

Ignorar signedness ou reduzir a máscara antes de uma operação que precisa de todos os bits.

Voltar à explicação
Empacotar meias palavras

a=0x12345678, b=0xABCDEF01. Calcula PKBT16(a, b).

Pista

PKBT16 forma (H1, H0)=(a.H0, b.H1).

Solução

Resultado 0x5678ABCD, porque a primeira parcela da concatenação ocupa a metade alta.

Confere a tua resposta:

  • Identifiquei H0 e H1 dos dois operandos.
  • Coloquei a.H0 na metade alta.
  • Coloquei b.H1 na metade baixa.

Erros frequentes

Tomar a primeira parcela como H0 ou trocar PKBT com PKTB.

Voltar à explicação
Produtos diretos e cruzados

Vias H0, H1: a=[−2,3], b=[4,5]. Indica resultados de SMUL16 e SMULX16.

Pista
Produtos de 16 bits geram resultados de 32 bits.
Solução

SMUL16:(baixo −8, alto 15); SMULX16:(baixo −10, alto 12). Cada par guarda dois produtos completos, não dois produtos de 16 bits em um registo.

Confere a tua resposta:

  • Obtive os dois produtos 32 bits diretos −8 e 15.
  • Obtive os cruzados −10 e 12.
  • Expliquei por que são necessários dois registos.

Erros frequentes

Truncar antes da operação seguinte sem justificar limites ou confundir ordem do par.

Voltar à explicação
Trocar a origem da segunda parcela

As vias são dadas por [H0,H1]: a=[8,30], b=[3,7]. Calcula as vias de STAS16(a,b) e CRAS16(a,b), sem overflow.

Pista

A instrução direta combina índices iguais; a cruzada usa o índice contrário de b.

Solução

Na ordem [H0,H1], STAS16 dá [5,37] e CRAS16 dá [1,33]. O sinal da operação depende da via e a origem de b depende de ser direta ou cruzada.

Confere a tua resposta:

  • Usei a ordem H0,H1 declarada.
  • Obtive STAS16=(5,37).
  • Obtive CRAS16=(1,33).

Erros frequentes

Trocar STAS16 com STSA16 ou interpretar a lista inicial como [H1,H0].

Voltar à explicação

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

Navegação

Cursor de leitura, sem edição. h, j, k, l movem; / pesquisa nesta página. v seleciona caracteres; V seleciona linhas; y copia. Tab permite destacar ou comentar. Espaço ou Enter abre blocos recolhíveis. Nos cartões, h, j, k, l mudam o foco.

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Copiar fórmula

A cópia automática não está disponível. Copia o LaTeX abaixo.

Pesquisar nesta página

Enter procura · n / N repetem · Esc cancela. Ctrl / Cmd K pesquisa todo o site.

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.