BR102013007865A2 - Aperfeiçoamento de desempenho de loops de partição vetorial - Google Patents

Aperfeiçoamento de desempenho de loops de partição vetorial Download PDF

Info

Publication number
BR102013007865A2
BR102013007865A2 BRBR102013007865-4A BR102013007865A BR102013007865A2 BR 102013007865 A2 BR102013007865 A2 BR 102013007865A2 BR 102013007865 A BR102013007865 A BR 102013007865A BR 102013007865 A2 BR102013007865 A2 BR 102013007865A2
Authority
BR
Brazil
Prior art keywords
vector
instruction
prediction
dependency
loop
Prior art date
Application number
BRBR102013007865-4A
Other languages
English (en)
Inventor
Jeffry E Gonion
Original Assignee
Apple Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Apple Inc filed Critical Apple Inc
Publication of BR102013007865A2 publication Critical patent/BR102013007865A2/pt

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/30003Arrangements for executing specific machine instructions
    • G06F9/30072Arrangements for executing specific machine instructions to perform conditional operations, e.g. using predicates or guards
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/30003Arrangements for executing specific machine instructions
    • G06F9/30007Arrangements for executing specific machine instructions to perform operations on data operands
    • G06F9/30036Instructions to perform operations on packed data, e.g. vector, tile or matrix operations
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/30003Arrangements for executing specific machine instructions
    • G06F9/3005Arrangements for executing specific machine instructions to perform operations for flow control
    • G06F9/30058Conditional branch instructions
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline or look ahead
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline or look ahead
    • G06F9/3836Instruction issuing, e.g. dynamic instruction scheduling or out of order instruction execution
    • G06F9/3838Dependency mechanisms, e.g. register scoreboarding
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline or look ahead
    • G06F9/3836Instruction issuing, e.g. dynamic instruction scheduling or out of order instruction execution
    • G06F9/3842Speculative instruction execution
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline or look ahead
    • G06F9/3836Instruction issuing, e.g. dynamic instruction scheduling or out of order instruction execution
    • G06F9/3842Speculative instruction execution
    • G06F9/3848Speculative instruction execution using hybrid branch prediction, e.g. selection between prediction techniques

Landscapes

  • Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Mathematical Physics (AREA)
  • Executing Machine-Instructions (AREA)
  • Devices For Executing Special Programs (AREA)
  • Advance Control (AREA)
  • Complex Calculations (AREA)

Abstract

Aperfeiçoamento de desempenho de loops de partição vetorial. A presente invenção refere-se a um método para eliminar previsão de instrução de desvio inverso, usada em um loop de partição vetorial, inclui detectar a primeira instrução de desvio inverso, que ocorre após uma instrução de geração de predicado. A instrução de geração de predicado gera um vetor de predicado, que é dependente de um vetor de dependência, em que cada elemento do vetor de dependência indica se existe uma dependência de dados entre os elementos de uma instrução vetorial. O método também inclui receber uma indicação de uma precisão de previsão de uma previsão da instrução de desvio inverso. Se a precisão de previsão não satisfizer um valor de limiar, a previsão de desvio inverso é eliminada, até que o vetor de dependência, do qual depende a instrução de geração de predicado, esteja disponivel.

Description

Relatório Descritivo da Patente de Invenção para "APERFEI- ÇOAMENTO DE DESEMPENHO DE LOOPS DE PARTIÇÃO VETORIAL".
ANTECEDENTES
CAMPO TÉCNICO A presente invenção refere-se a processadores, e, mais particu- larmente, à previsão de certas instruções de desvio, durante execução de loops de partição vetorial.
DESCRIÇÃO DA TÉCNICA RELACIONADA A previsão de desvio se tornou lugar comum nos processadores mais modernos. Ainda que os desvios para trás possam ser, em muitos ca- sos, altamente previsível, alguns desvios para trás podem ser previstos mui- to mal por previsores de desvio. Mais particularmente, os processadores e compiladores macroescalares se baseiam em loops de partição vetorial, pa- ra manusear, corretamente, as possíveis dependências conduzidas pelos loops, tais como riscos de memória, por exemplo. Os loops de partição veto- ríal são desvios para trás para iteração no loop. Nós casos nos quais o vetor é dividido frequentemente, o previsor de desvio convencional pode executar muito mal, o que pode afetar adversamente o desempenho do processador.
SUMÁRIO DAS CONCRETIZAÇÕES Várias concretizações de um método para eliminar previsão de uma instrução de desvio para trás, usadas em um loop de partição vetorial, são descritas. De um modo geral, um método é considerado no qual a pri- meira instrução de desvio para trás, que ocorre após uma instrução de gera- ção de predicado ser detectada. A instrução de geração de predicado gera um vetor de instrução de geração de predicado, que é dependente de um vetor de dependência, em que cada elemento do vetor de dependência indi- ca se existe uma dependência de dados entre os elementos de uma instru- ção vetorial. Se uma indicação recebida de uma precisão de precisão de uma previsão de desvio para trás não satisfizer um valor de limiar, a previ- são da instrução de desvio para trás pode ser eliminada, até que o vetor de dependência, do qual depende a instrução de geração de predicado, esteja disponível.
Em uma concretização, o método inclui detectar uma primeira instrução de desvio condicional, que se segue a uma instrução de geração de predicado. A instrução de geração de predicado, quando executada, gera um vetor de predicado em um vetor de dependência. Cada elemento do ve- tor de dependência inclui um índice, que indica se existe uma dependência de dados entre os elementos de uma instrução vetorial. Além disso, o méto- do pode incluir receber uma indicação de uma precisão de previsão da pri- meira instrução de desvio condicional. Em resposta à determinação de que a precisão de previsão da primeira instrução de desvio condicional não satis- faz um valor de limiar, a previsão da primeira instrução de desvio condicional pode ser eliminada, até que o vetor de dependência, do qual depende a ins- trução de geração de predicado, esteja disponível.
Em uma implementação específica, o método pode incluir tam- bém prever a primeira instrução de geração de predicado, responsiva à de- tecção de que o vetor de dependência está disponível, usando as informa- ções dêlle^èndênaá dè dados indicadas ncívêtbTde^êpendêr^ BREVE DESCRICÀO DOS DESENHOS A Figura 1 é um diagrama de blocos de uma concretização de um sistema computadorizado. A Figura 2 é um diagrama de blocos ilustrando detalhes adicio- nais de uma concretização do processador, mostrado na Figura 1. A Figura 3 é um diagrama ilustrando uma paralelização de um loop de código de programa. A Figura 4A é um diagrama ilustrando uma sequência de esta- dos variáveis, durante execução escalar do loop mostrado no Exemplo 1. A Figura 4B é um diagrama ilustrando uma progressão de exe- cução de um código de programa vetorizado macroescalar do loop do E- xemplo 1.
As Figuras 5A e 5B são diagramas ilustrando uma concretização da vetorização de código de fonte de programa. A Figura 6A é um diagrama ilustrando uma concretização de có- digo de programa vetorizado não especulativo. A Figura 6B é um diagrama ilustrando uma outra concretização de código de programa vetorizado especulativo. A Figura 7 é um diagrama ilustrando uma concretização de códi- go de programa vetorizado. A Figura 8 é um diagrama ilustrando outra concretização de có- digo de programa vetorizado. A Figura 9 é um fluxograma ilustrando a operação de uma con- cretização do processador da Figura 2, durante execução de instruções de programa que formam um loop de partição vetorial.
Concretizações específicas são mostradas por meio de exemplo nos desenhos e vão ser, no presente relatório descritivo, descritas em deta- lhes. Deve-se entender, no entanto, que os desenhos e a descrição detalha- da não são intencionados para limitar as reivindicações às concretizações particulares descritas, mesmo quando apenas uma única concretização for descrita com relação a um aspecto particular. Ao contrário, a intenção é a de cobrir todas as modificações, equivalentes e alternativas, que vão ser evi- dentes para uma pessoa versada na técnica, tendo o benefício desta descri- ção. Os exemplos de aspectos proporcionados na descrição são intenciona- dos para serem ilustrativos, em vez de restritivos, a menos que indicado de outro modo.
Como usada ao longo deste relatório descritivo, a palavra "pode" é usada em um sentido permissivo (isto é, significando que tem o potencial para), em vez de um sentido mandatário (isto é, significando deve). De modo similar, as palavras "incluir", "incluindo" e "inclui" significam incluindo, mas não limitado a. Várias unidades, circuitos ou outros componentes podem ser descritos como "configurados para" executar uma ou mais tarefas. Nesses contextos, "configurado para" é uma recitação ampla de estrutura indicando geralmente "tendo um conjunto de circuitos que" executa a tarefa ou as tare- fas durante a operação. Como tal, a unidade / circuito / componente podem ser configurados para executar a tarefa, mesmo quando os unidade / circuito / componente não estão ligados. Em geral, o conjunto de circuitos, que for- ma a estrutura correspondente a "configurado para", pode incluir circuitos de hardware. De modo similar, as várias unidades / circuitos / componentes po- dem ser descritos como executando uma tarefa ou tarefas, para conveniên- cia na descrição. Essas descrições devem ser interpretadas como incluindo a frase "configurado para". Quando da descrição de umas unidade / circuito / componente, que são configurados para executar uma ou mais tarefas, pre- tende-se expressamente não invocar a interpretação da norma 35 U.S.C. ξ 112, parágrafo seis, para esses unidades / circuito / componente. O âmbito da presente invenção inclui qualquer aspecto ou com- binação de aspectos descrito no presente relatório descritivo (implícita ou explicitamente), ou qualquer generalização dele, se ou não atenua quaisquer ou todos os problemas abordados no presente relatório descritivo. Conse- quentemente, novas reivindicações podem ser formuladas durante a continu- idade deste pedido de patente (ou um pedido de patente reivindicando prio- ridade a ele. Em particular, com referência às reivindicações em anexo, os aspectos das reivindicações dependentes podem ser combinados com aque- les das reivindicações independentes, e os aspectos das reivindicações in- dependentes podem ser combinados em qualquer maneira adequada e não meramente nas combinações específicas enumeradas nas reivindicações em anexo.
DESCRIÇÃO DETALHADA
Visão geral de sistema computadorizado Voltando então à Figura 1, um diagrama de blocos de uma con- cretização de um sistema computadorizado é mostrado. O sistema compu- tadorizado 100 inclui um processador 102, um cache de dois níveis (L2), uma memória 108 e um dispositivo de armazenamento de massa 110. Como mostrado, o processador 102 inclui um cache de um nível (L1) 104. Deve-se notar que embora os componentes específicos sejam mostrados e descritos no sistema computadorizado 100, em concretizações alternativas, diferentes componentes e vários componentes podem estar presentes no sistema computadorizado 100. Por exemplo, o sistema computadorizado 100 pode não incluir parte da hierarquia de memória (por exemplo, a memória 108 e/ou o dispositivo de armazenamento de massa 110). Alternativamente, em- bora o cache L2 106 seja mostrado externo ao processador 102, considera- se que, em outras concretizações, o cache L2 106 pode ser interno ao pro- cessador 102. Deve-se notar ainda que nessas concretizações, um cache de três níveis (L3) (não mostrado) pode ser usado. Além disso, o sistema com- putadorizado 100 pode incluir processadores gráficos, cartões de vídeo, dis- positivos de captura de vídeo, dispositivos de interface com usuário, cartões de rede, unidades ópticas e/ou outros dispositivos periféricos, que são aco- plados ao processador 102, usando um barramento, uma rede ou outro ca- nal de comunicação adequado (todos não mostrados por simplicidade).
Em várias concretizações, o processador 102 pode ser repre- sentativo de um processador genérico, que executa operações computacio- nais. Por exemplo, o processador 102 pode ser uma unidade de processa- mento central (CPU), tal como um microprocessador, um microcontrolador, um circuito integrado de aplicação específica (ASIC), ou uma disposição de porta programável no campo (FPGA). No entanto, como descrito adicional- mente abaixo, o processador 102 pode incluir um ou mais mecanismos para processamento vetoriai (por exemplo, unidades de execução vetorial). Uma unidade de execução vetorial exemplificativa do processador 102 é descrita em mais detalhes abaixo, em conjunto com a descrição da Figura 2. O dispositivo de armazenamento de massa 110, a memória 108, o cache L2 10 e o cache L1 104 são dispositivos de armazenamento, que formam coletivamente uma hierarquia de memória, que armazena dados e instruções para o processador 102. Mais particularmente, o dispositivo de armazenamento de massa 110 pode ser uma memória não volátil de alta capacidade, tal como uma unidade de disco ou uma grande unidade de me- mória instantânea com um longo tempo de acesso, enquanto que o cache L1 104, o cache L2 106 e a memória 108 podem ser menores, com tempos de acesso mais curtos. Essas memórias semicondutoras mais rápidas armaze- nam cópias de dados usados frequentemente. A memória 108 pode ser re- presentativa de um dispositivo de memória na família de memória dinâmica de acesso aleatório (DRAM) DE dispositivos de memória. O tamanho da memória 108 é tipicamente maior do que aqueles dos cache L1 104 e cache L2 106, enquanto que os cache L1 104 e cache L2 106 são tipicamente im- plementados por uso de dispositivos menores na família de memórias estáti- cas de acesso aleatório (SRAM) de dispositivos. Em algumas concretiza- ções, o cache L2 106, a memória 108 e o dispositivo de armazenamento de massa 110 são compartilhados entre um ou mais processadores no sistema computadorizado 100.
Em algumas concretizações, os dispositivos na hierarquia de memória (isto é, o cache L1 104, etc.) podem acessar (isto é, ler e/ou escre- ver) múltiplas linhas de cache por ciclo. Essas concretizações podem permi- tir um processamento mais efetivo de acessos de memória, que ocorrem com base em um vetor de ponteiros ou uma disposição de índices para en- dereços de memórias não contíguos.
Deve-se notar que as estruturas de dados e as instruções (isto é, código) de programas descritos abaixo podem ser armazenadas em um dispositivo de armazenamento legível por computador não transitório, que pode ser qualquer dispositivo ou meio de armazenamento, que possa arma- zenar código e/ou dados para uso por um sistema computadorizado (por exemplo, o sistema computadorizado 100). De um modo geral, um dispositi- vo de armazenamento legível por computador não transitório inclui, mas não é limitado a, uma memória volátil, uma memória não volátil, dispositivos de armazenamento magnéticos e ópticos tais como unidades de disco, fita magnética, discos compactos (CDs), discos versáteis digitais ou videodiscos digitais (DVDs), ou outros meios capazes de armazenar meios legíveis por computador atualmente conhecidos ou de desenvolvimento posterior. Como tal, o dispositivo de armazenamento de massa 110, a memória 108, o cache L2 106 e o cache L1 104 são todos exemplos de dispositivos de armazena- mento legíveis por computador não transitórios.
Processador Com referência à Figura 2, um diagrama de blocos, ilustrando detalhes adicionais de uma concretização do processador da Figura 1, é mostrado. Na concretização mostrada na Figura 2, o processador 102 pode incluir vários estágios de encadeamento, embora, por brevidade, nem todos são mostrados na Figura 2. Consequentemente, como mostrado, o proces- sador 102 inclui o cache L1 104, uma unidade de recuperação de instruções 201, uma unidade de previsão de desvio 210, uma unidade de previsão in- correta 212, uma unidade de execução de números inteiros 201, uma unida- de de execução de ponto flutuante 206 e uma unidade de execução vetorial 204. Deve-se notar que a unidade de execução de números inteiros 202, a unidade de execução de ponto flutuante 206 e a unidade de execução veto- rial 204, como um grupo, podem ser referidas intercambiavelmente como as "unidades de execução".
Em várias concretizações, as unidades de execução podem e- xecutar operações computacionais, tais como operações lógicas, operações matemáticas ou operações de ação bit a bit, por exemplo, para um tipo de item operável associado. Mais especificamente, a unidade de execução de números inteiros 202 pode executar operações computacionais, que envol- vem itens operáveis de números inteiros, a unidade de execução de ponto flutuante 206 pode executar operações computacionais que envolvem itens operáveis de ponto flutuante, e a unidade de execução vetorial 204 pode executar operações computacionais, que envolvem itens operáveis vetoriais.
As unidades de execução de números inteiros e as unidades de execução de ponto flutuante são geralmente conhecidas na técnica e não são descri- tas adicionalmente por brevidade. Como mencionado acima, embora a con- cretização do processador 102, mostrado na Figura 2, inclua um conjunto de componentes particular, considera-se que, em concretizações alternativas, o processador 102 pode incluir diferentes números ou tipos de unidades de execução, unidades funcionais e estágios de encadeamento, tal como uma unidade de decodifícação de instruções, um escalonador ou estações de reserva, um armazenamento temporário de reordenação, uma unidade de controle de memória, interfaces l/O, etc, que podem ser acoplados às unida- des de execução. A unidade de execução vetorial 204 pode ser representativa de uma unidade de execução de dados múltiplos de instrução única (SIMD) no sentido clássico, pelo fato de que pode executar a mesma operação em múl- tiplos elementos de dados em paralelo. No entanto, deve-se notar que, em algumas concretizações, as instruções vetoriais, descritas no presente rela- tório descritivo, podem ser diferentes de outras implementações de instru- ções SIMD. Por exemplo, em uma concretização, os elementos de um vetor operados por uma instrução vetorial podem ter um tamanho que não varia com o número de elementos no vetor. Em comparação, em algumas imple- mentações SIMD, o tamanho dos elementos de dados varia com o número de elementos de dados operados (por exemplo, uma arquitetura SIMD pode suportar operações em oito elementos de oito bits, mas apenas quatro ele- mentos de 16 bits, dois elementos de 32 bits, etc.). Em uma concretização, a unidade de execução vetorial 204 pode operar em alguns ou todos dos ele- mentos de dados, que são incluídos em vetores de itens operáveis. Mais particularmente, a unidade de execução vetorial 204 pode ser configurada para operar concorrentemente em diferentes elementos de um item operável vetorial de uma instrução de programas vetoriais.
Em uma concretização, a unidade de execução vetorial 204 po- de incluir um arquivo de registradores vetoriais (não mostrado), que pode incluir registradores vetoriais, que podem reter vetores de itens operáveis e gerar vetores para a unidade de execução vetorial 204. Em algumas concre- tizações, pode haver 32 registradores vetoriais no arquivo de registradores vetoriais, e cada registrador vetorial pode incluir 128 bits. No entanto, em concretizações alternativas, pode haver diferentes números de registradores vetoriais e/ou diferentes números de bits por registro. A unidade de execução vetorial 204 pode ser configurada para recuperar itens operáveis dos registradores operáveis, e executar instruções vetoriais, que fazem com que a unidade de execução vetorial 204 execute operações em paralelo em alguns ou em todos dos elementos de dados no vetor de item operável. Por exemplo, a unidade de execução vetorial 204 pode executar operações lógicas, operações matemáticas ou operações bit a bit nos elementos no vetor. A unidade de execução vetorial 204 pode exe- cutar uma operação vetorial por ciclo de instrução (embora como descrito acima, um "ciclo" pode incluir mais de um ciclo de sincronização, que podem ser usados para disparar, sincronizar e/ou controlar as operações computa- cionais da unidade de execução vetorial 204).
Em uma concretização, a unidade de execução vetorial 204 po- de suportar vetores que retêm N elementos de dados (por exemplo, bytes, palavras, palavras duplas, etc.), em que N pode ser qualquer número inteiro positivo. Nessas concretizações, a unidade de execução vetorial 204 pode executar operações em N ou menos dos elementos de dados em um vetor de item operável em paralelo. Por exemplo, em uma concretização na qual o vetor é de um comprimento de 256 bits, os elementos de dados operados são elementos de quatro bytes, e a operação incorpora um valor aos ele- mentos de dados, essas concretizações podem incorporar o valor a presente invenção número dos elementos no vetor. Deve-se notar que N pode ser diferente para diferentes implementações do processador 102. A unidade de execução vetorial 204 pode, em várias concretiza- ções, incluir pelo menos um sinal de controle, que propicie a limitação dinâ- mica dos elementos de dados em um vetor de item operável, no qual a uni- dade de execução vetorial 204 opera. Especificamente, dependendo do es- tado do sinal de controle, a unidade de execução vetorial 204 pode operar, seletivamente, em qualquer um ou em todos os elementos de dados no ve- tor. Por exemplo, em uma concretização na qual o vetor é de um compri- mento de 512 bits e os elementos de dados operados são elementos de quatro bytes, o sinal de controle pode ser estabelecido para impedir opera- ções de serem executadas em alguns ou todos de 16 elementos de dados no vetor de item operável. Notar que a limitação "dinâmica" dos elementos de dados no vetor de item operável, no qual as operações são conduzidas, pode envolver garantir o sinal de controle separadamente para cada ciclo, durante a execução.
Em algumas concretizações, como descrito em mais detalhes abaixo, com base nos valores contidos em um vetor de predicados ou em um ou mais predicados escalares, a unidade de execução vetorial 204 aplica operações vetoriais apenas aos elementos de dados vetoriais. Em algumas concretizações, os elementos de dados remanescente se mantêm, em um vetor resultante, sem serem afetados (que também pode ser referido como uma "predicação") ou são forçados a zero (o que pode ser também referido como "zeramento" ou "predicação de zeramento"). Em algumas concretiza- ções, os relógios para os subsistemas de processamento de elementos ("pistas", que não são usados, devido à predicação ou zeramento na unida- de de execução vetorial 204, pode ser em portas de energia e/ou sincroniza- ção, reduzindo, desse modo, o consumo dinâmico de energia em uma uni- dade de execução vetorial 204.
Em várias concretizações, a arquitetura pode ser um agnóstico de comprimento vetorial, para permitir que ela adapte o paralelismo, durante a execução. Mais particularmente, quando instruções ou operações são ag- nósticos de comprimento vetorial, a operação (isto é, a instrução, etc.) pode ser executada por uso de vetores de qualquer comprimento, até as limita- ções impostas pelo hardware de suporte. Por exemplo, nas concretizações nas quais o hardware de execução vetorial suporta os vetores, que podem incluir oito elementos de quatro bytes separados (tendo, desse modo um comprimento de vetor de oito elementos), uma operação agnóstica de com- primento vetorial pode operar em qualquer número dos oito elementos no vetor. Em uma diferente implementação de hardware, que suporta um dife- rente comprimento vetorial (por exemplo, quatro elementos), a operação ag- nóstica de comprimento vetorial pode operar no número diferente de ele- mentos disponibilizados para ela pelo hardware associado. Desse modo, um compilador ou programador não precisa ter conhecimento explícito do com- primento do vetor suportado pelo hardware associado (por exemplo, unidade de execução vetorial 204). Nessas concretizações, um compilador gera ou um programador escreve um código de programa, que não precisa se base- ar (ou usar) um comprimento vetorial específico. Em algumas concretiza- ções, pode-se esquecer de especificar um tamanho vetorial específico em um código de programa. Desse modo, o código compilado nessas concreti- zações (isto é, o código binário) é executado em outras unidades de execu- ção, que podem ter diferentes comprimentos vetoriais, enquanto promoven- do, potencialmente, ganhos de desempenho dos processadores que supor- tam vetores mais longos. Nessas concretizações, o comprimento do vetor pode, para uma determinada unidade de hardware, tal como um processa- dor, ser lido de um registrador de sistema, durante a operação. Consequen- temente, como a tecnologia de processamento propicia vetores mais longos, a execução de código binário herdado é acelerada, sem qualquer esforço por desenvolvedores de software.
Geralmente, os comprimentos vetoriais podem ser implementa- dos como potências de dois (por exemplo, dois, quatro, oito, etc.). No entan- to, em algumas concretizações, os comprimentos vetoriais não precisam ser potências de dois. Especificamente, os vetores de três, sete ou outro número de elementos de dados podem ser usados do mesmo modo que os vetores com potências de dois números de elementos de dados.
Em várias concretizações, cada elemento de dados no vetor po- de conter um endereço, que é usado pela unidade de execução vetorial 204, para execução de um conjunto de acessos de memória em paralelo. Nessas concretizações, se um ou mais elementos do vetor contêm endereços de memórias inválidas, as operações de leitura de memórias inválidas podem ocorrer. Consequentemente, as operações de leitura de memórias inválidas, que resultariam, de outro modo, em terminação de programa, podem, em vez disso, fazer com que quaisquer elementos com endereços válidos sejam lidos e elementos com elementos inválidos sejam marcados, permitindo que a execução do programa continue diante de operações de leitura especulati- vas, e percebidas como ilegais.
Em algumas concretizações, o processador 102 (e, por conse- guinte, a unidade de execução vetorial 204) é capaz de operar e usar veto- res de ponteiros. Nessas concretizações, o número de elementos de dados por vetor é igual ao número de ponteiros por vetor, independentemente do tamanho do tipo de dados. As instruções que operam na memória podem ter variantes que indicam o tamanho do acesso de memória, mas os elementos nos registros do processador devem ser iguais ao tamanho do ponteiro.
Nessas concretizações, os processadores, que suportam ambos os modos de endereçamento de 32 bits e 64 bits, podem selecionar permitir o dobro dos elementos por vetor no modo de 32 bits, obtendo, desse modo, uma maior taxa de rendimento. Isso implica em uma vantagem de taxa de rendi- mento para endereçamento de 32 bits, considerando a rota de dados de mesma amplitude. As técnicas específicas de implementação podem ser usadas para relaxar o requisito. Por exemplo, os números de pontos flutuan- tes de precisão dupla podem ser suportados em modo de 32 bits por empa- relhamento de registros, ou algum outro mecanismo especializado.
Em uma concretização, a unidade de previsão de desvio 210 pode ser configurada para gerar endereços contadores de programas alvo de desvio (PCs) para a unidade de recuperação 201, para instruções de desvio condicional. Mais particularmente, para instruções de desvio condi- cional, a unidade de previsão de desvio 210 pode prever se um desvio vai ser adotado ou não, e a lógica de controle (não mostrada) pode gerar o PC para a unidade de recuperação 201, com base na previsão. As instruções podem ser recuperadas, emitidas e executadas em uma maneira especulati- va, dependente do resultado previsto do desvio. Em várias concretizações, a unidade de previsão de desvio 210 pode usar quaisquer de vários mecanis- mos de previsão para gerar as previsões. Por exemplo, a unidade de previ- são de desvio 210 pode usar previsores locais, que mantêm o estado de previsão (por exemplo, máquinas de estado, tabelas, contadores ou outras estruturas de dados) para desvios individuais, previsores globais, que execu- tam previsão por desvios múltiplos considerados nos previsores híbridos, agregados, que combinam elementos dos previsores locais e globais, ou outras abordagens adequadas. Em algumas concretizações, a unidade de previsão de desvio 210 pode empregar previsores, que se adaptam dinami- camente ao comportamento de desvio, que varia durante a execução (por exemplo, para detectar e adaptar-se quando um desvio, que foi melhor pre- visto, de acordo com uma técnica, fica melhor previsto, de acordo com uma técnica diferente).
Em uma concretização, a unidade de previsão incorreta 212 é configurada para detectar quando uma previsão de desvio está incorreta (por exemplo, que o comportamento efetivo de um desvio, quando de sua execu- ção, difere do comportamento previsto do desvio, indicando que o desvio foi previsto incorretamente). Além disso, a unidade de previsão incorreta 212 pode ser configurada para proporcionar uma indicação da previsão incorreta para as unidades de execução 202, 206 e 204, bem como para a unidade de previsão de desvio 210. Deve-se notar que embora a unidade de previsão incorreta 212 seja mostrada com uma unidade separada, considera-se que, em outras concretizações, a unidade de previsão incorreta 212 pode ser par- te da unidade de previsão de desvio 210, ou pode ser parte da unidade de recuperação 201, ou pode ser parte de quaisquer das várias unidades de execução (por exemplo, 202, 204 e 206).
Como descrito acima, quando um processador convencional prevê incorretamente uma instrução de desvio, o encadeamento é esvaziado das instruções na rota prevista incorretamente, porque essas instruções emi- tidas especulativamente não devem ser deixadas modificar o estado do pro- cessador, em vista da especulação incorreta. A unidade de recuperação 201 pode então recuperar as instruções para a rota não especulativa, correta. No entanto, há uma penalidade para a operação de esvaziamento e enchimen- to: centenas de ciclos de execução podem ser necessários, antes que traba- lho útil possa ser restabelecido.
Consequentemente, como descrito em mais detalhes abaixo em conjunto com a descrição da Figura 7, em uma concretização, a unidade de previsão de desvio 210 pode manter informações de precisão de previsão para as várias previsões. As informações de precisão para uma determinada instrução de desvio pode ser adaptada com base no comportamento efetivo da instrução de desvio, desde que seja executada, em comparação com o modo no qual a instrução de desvio foi prevista se comportar. Para evitar alguma penalidade associada com desvios para trás de previsão incorreta, usados em loops de partição vetorial, quando a precisão de previsão é má, a unidade de previsão de desvio 210 pode ser configurada para eliminar e previsão e aguardar que as informações correspondentes ao número de ite- rações do loop fiquem disponíveis.
Visão gerai de arquitetura macroescalar Uma arquitetura de conjunto de instruções (referida como arqui- tetura macroescalar) e um hardware de suporte podem permitir que compi- ladores gerem um código de programa para loops, sem que tenham que de- terminar completamente o paralelismo quando da compilação, e sem descar- tar informações de análises estáticas úteis. Várias concretizações da arquite- tura macroescalar vão ser descritas a seguir. Especificamente, como descri- to adicionalmente acima, um conjunto de instruções é proporcionado, que não impõe o paralelismo para os loops, mas, em vez disso, permite que o paralelismo seja explorado durante a execução, se as condições dinâmicas permitirem. Consequentemente, a arquitetura inclui instruções, que permitem que o código, gerado pelo compilador, se alterne dinamicamente entre exe- cução não paralela (escalar) e paralela (vetorial) para as iterações de loops, dependendo das condições quando da execução por variação do grau de paralelismo usado.
Desse modo, a arquitetura proporciona instruções que permitem que um grau indeterminado de paralelismo vetorial, mas que não precise que o paralelismo seja usado durante a execução. Mais especificamente, a arquitetura inclui um conjunto de instruções agnósticas de comprimento ve- torial, cujo comprimento vetorial efetivo pode variar, dependendo das condi- ções durante a execução. Desse modo, se dependências do tempo de exe- cução demandam execução não paralela do código, então a execução ocor- re com um comprimento vetorial efetivo de um elemento. Igualmente, se as condições durante a execução permitirem execução paralela, o mesmo có- digo é executado em uma maneira paralela vetorial em qualquer grau que seja permitido pelas dependências do tempo de execução (e comprimento vetorial do hardware associado). Por exemplo, se dois dos oito elementos do vetor puderem ser executados com segurança em paralelo, um processador, tal como o processador 102, pode executar os dois elementos em paralelo.
Nessas concretizações, a expressão do código de programa em um formato agnóstico de comprimento vetorial propicia uma ampla gama de oportunida- des de vetorização, que não estão presentes nos sistemas existentes.
Em várias concretizações, durante a compilação, um compilador analisa primeiro a estrutura de loop de um determinado loop em código de programa, e executa análise de dependência estática. O compilador então gera um código de programa, que retém informações de análise estática e instrui um processador, tal como o processador 102, por exemplo, de como resolver as dependências do tempo de execução e processar o código de programa com o grau de paralelismo máximo possível. Mais especificamen- te, o compilador pode proporcionar instruções vetoriais para execução dos conjuntos correspondentes de iterações do loop em paralelo, e pode propor- cionar instruções de controle vetorial, para limitar dinamicamente a execução das instruções vetoriais, para impedir que as dependências de dados entre as iterações do loop provoquem um erro. Essa abordagem retarda a deter- minação de paralelismo durante a execução, quando as informações das dependências do tempo de execução estão disponíveis, permitindo, desse modo, que o software e o processador adaptem o paralelismo para as condi- ções de variação dinâmica. Um exemplo de uma paralelização de loop de código de programa é mostrado na Figura 3.
Com referência ao lado esquerdo da Figura 3, um modelo de execução é mostrado com quatro iterações (por exemplo, as iterações 1-4) de um loop que não foi paralelizado, em que cada loop inclui as instruções A - G. As operações em série são mostradas com as instruções empilhadas verticalmente. No lado direito da Figura 3 fica uma versão do loop que foi paralelizado. Neste exemplo, cada instrução dentro de uma iteração depen- de pelo menos de uma instrução antes dela, de modo que haja uma cadeia de dependência estática entre as instruções de uma determinada iteração.
Por conseguinte, as instruções dentro de uma determinada iteração não po- dem ser paralelizadas (isto é, as instruções A - B, dentro de uma determina- da iteração, são sempre executadas em série com relação às outras instru- ções na iteração). No entanto, em concretizações alternativas, as instruções, dentro de uma determinada iteração, podem ser paralelizáveis.
Como mostrado pelas setas entre as iterações do loop na Figura 3, há uma possibilidade de uma dependência de dados durante a execução, entre a instrução E em uma determinada iteração e a instrução D da iteração subsequente. No entanto, durante a compilação, o compilador pode apenas determinar que existe a possibilidade de dependência de dados entre essas instruções, mas o compilador não pode indicar que dependências de itera- ções vão de fato se materializar, porque essas informações estão apenas disponíveis durante a execução. Neste exemplo, uma dependência de da- dos, que se materializa de fato durante a execução, é mostrada pelas setas sólidas de 1E a 2D, e de 3E a 4D, enquanto que uma dependência de da- dos, que não se materializa durante a execução, é mostrada usando a seta tracejada de 2E a 3D. Desse modo, como mostrado, uma dependência de dados durante a execução ocorre de fato entre as primeira / segunda e ter- ceira / quarta iterações.
Em virtude de não existir qualquer dependência de dados entre as segunda e terceira iterações, as segunda e terceira iterações podem ser processadas com segurança em paralelo. Além do mais, as instruções A - C e F - G, de uma determinada iteração, têm dependências apenas dentro de uma iteração e, portanto, a instrução A de uma determinada iteração é ca- paz de ser executada em paralelo com a instrução A de todas as outras ite- rações, a instrução B pode também ser executada em paralelo com a instru- ção B de todas as outras iteração, e assim por diante. No entanto, em virtu- de da instrução D, na segunda iteração, depender da instrução E, na primei- ra iteração, as instruções D e E, na primeira iteração, devem ser executadas antes da instrução D, para a segunda iteração, poder ser executada.
Consequentemente, no loop paralelizado no lado direito, as ite- rações desse loop são executadas para acomodar ambas as dependências de dados estáticas e durante a execução, enquanto obtendo um paralelismo máximo. Mais particularmente, as instruções A-CeF-Gde todas as qua- tro iterações são executadas em paralelo. Mas, em virtude da instrução D, na segunda iteração, depender da instrução E, na primeira iteração, as ins- truções D e E, na primeira iteração, devem ser executadas antes da instru- ção D, para a segunda iteração, poder ser executada. No entanto, em virtu- de de não haver dependência de dados entre as segunda e terceira itera- ções, as instruções D e E, para essas iterações, podem ser executadas em paralelo.
Exemplos da arquitetura macroescalar Os exemplos apresentados a seguir introduzem operações ma- croescalares e demonstram o uso delas em loops de vetorização, tal como o loop mostrado na Figura 3 e descritos acima no exemplo de loop paraleliza- do. Para facilidade de entendimento, esses exemplos são apresentados por uso de um pseudocódigo no formato C++.
Deve-se notar que as concretizações exemplificativas apresen- tadas a seguir são para fins de discussão. As instruções e operações efeti- vas são meramente intencionadas para ajudar no entendimento da arquitetu- ra. No entanto, em concretizações alternativas, as instruções ou operações podem ser implementadas de um modo diferente usando, por exemplo, uma sequência de microcódigos de operações mais primitivas, ou usando uma sequência diferente de suboperações. Notar que uma decomposição adicio- nal de instruções é evitada, de modo que as informações sobre a macro- operação e o modelo de uso correspondente não fique obscurecidas.
Notação Na descrição dos exemplos apresentados abaixo, o formato a~ presentado a seguir é usado para as variáveis, que são quantidades vetori- ais, a menos que indicadas de outro modo: p5 = a<b;
Os elementos do vetor p5 são ajustados em 0 ou 1, dependendo do teste a < b. Notar que o vetor p5 pode ser um "vetor de predicado", como descrito em mais detalhes abaixo. Algumas instruções, que geram vetores de predicado, também ajustam os indicadores de estado do processador, para refletir os predicados resultantes. Por exemplo, os indicadores de estado ou códigos condicionais do processador podem incluir os indicadores FIRST, LAST, ΝΟΝΕ, e/ou ALL. “p5; a=b+c;
Apenas os elementos no vetor 'a' indicados por elementos ativos (isto é, diferentes de zero) no vetor de predicado p5 recebem o resultado de b+c. Os elementos remanescentes de a ficam inalterados. Essa operação é chamada "predicação" e é denotada usando o sinal de til antes do vetor de predicado. !p5; a=b+c;
Apenas os elementos no vetor 'a' indicados por elementos ativos (isto é, diferentes de zero) no vetor de predicado p5 recebem o resultado de b+c. Os elementos remanescente de a são ajustados em zero. Essa operação é chamada "zeramento", e é denotada por uso do sinal de ponto de exclamação ("!"), antes do vetor de predicado, if (FIRSTO) goto ...; //Also LAST(), ANY(), ALL(), CARRY(), ABOVE(), or NONE(), (where ANY() == !NONE()) As instruções apresentadas a seguir testam, consequentemente, os indicadores de estado e o desvio do processador. x+=VECLEN; VECLEN é um valor de máquina, que comunica o número de elementos por vetor. O valor é determinado quando da execução pelo processador do código, em vez de ser determinado pelo montador. //Comment Em um modo similar a muitas linguagens de programação comuns, os exemplos apresentados a seguir usam a barra oblíqua dupla para frente para indicar os comentário. Esses comentários podem proporcionar informações relativas aos valores contidos no vetor indicado, ou uma explicação das operações que são feitas em um exemplo correspondente.
Nesses exemplos, outros operadores formatados em C++- mantém os seus significados convencionais, mas são aplicados pelo vetor em uma base de elemento por elemento. Quando chamadas de funções são empregadas, implicam em uma instrução única, que coloca qualquer valor retornado em um registro de destino. Para simplicidade no entendimento, todos os vetores são vetores de números inteiros, mas concretizações alternativas suportam outros formatos de dados.
Dependências conduzidas por loops estruturais No Exemplo de código 1 apresentado abaixo, um loop de código de programa, que é "não vetorizável", usando arquiteturas vetoriais convencionais, é mostrado. (Notar que além de ser não vetorizável, esse loop é também não encadeável em arquiteturas de multiencadeamento convencionais, devido à natureza de grão fino das dependências de dados.) Para clareza, esse loop foi destilado para as dependências fundamentais conduzidas pelo loop, que tornam o loop não vetorizável.
Neste exemplo, as variáveis r e s têm dependências conduzidas pelo loop, que apresentam vetorização usando arquiteturas convencionais.
Prestar atenção, no entanto, que o loop seja vetorizável, uma vez que a condição (A [x] < FACTOR) é conhecida como sendo sempre verdadeira ou sempre falsa. Essas considerações mudam quando a condição é deixada variar durante a execução. Para simplicidade nesse exemplo, supõe-se que não exista qualquer nome alternativo entre A[] e BQ; EXEMPLO 1: Loop de código de programa r = 0; s = 0; for (x=0; x<KSIZE; ++x) { if (A[x] < FACTOR) { r = A[x+s]; } else { s = A[x+r]; } B[x] = r + s; } Usando a arquitetura macroescalar, o loop no Exemplo 1 pode ser vetorizado por partição do vetor em segmentos para os quais a condição (A [x] < FACTOR) não varia. Os exemplos de métodos para partição desses vetores, bem como os exemplos de instruções que possibilitem a partição, são apresentados abaixo. Deve-se notar que para esse exemplo, a partição descrita precisa ser apenas aplicada às instruções dentro da cláusula condicional. A primeira leitura de A[x] e a operação final B[x]=r+s podem ser sempre executadas em paralelo por um vetor integral, exceto potencialmente na iteração de loop final.
As instruções e os exemplos de código vetorizado são mostrados e descritos para explicar a operação de um processador de vetores, tal como o processador 102 da Figura 2, em conjunto com a arquitetura macroescalar. A descrição apresentada a seguir é geralmente organizada de modo que várias instruções sejam descritas, e depois uma ou mais amostras de códigos vetorizados, que usam as instruções, sejam apresentadas. Em alguns casos, um tipo particular de aspecto de vetorização é explorado em um determinado exemplo. dest=VectorReadlnt(Base, Offset) A VectorReadlnt é uma instrução para execução de uma operação de leitura de memória. Um vetor de desvios, Offset, escalonado pelo tamanho de dados (número inteiro neste caso), é adicionado a um endereço de base escalar, Base, para formar um vetor de endereços de memória, que são depois lidos em um vetor de destino. Se a instrução for predicada ou zerada, apenas os endereços correspondentes aos elementos ativos são lidos. Nas concretizações descritas, as leituras para invalidar endereços são permitidas falhar, mas essas falhas apenas resultam em terminação de programa, se o primeiro endereço ativo for inválido.
VectorWritelnt(Base, Offset, Value) A VectorWritelnt é uma instrução para execução de uma operação de escrita em memória. Um vetor de desvios, Offset, escalonado pelo tamanho de dados (número inteiro neste caso), é adicionado a um endereço de base escalar, Base, para formar um vetor de endereços de memória. Um vetor de valores, Value, é escrito nesses endereços de memória. Se esta instrução for predicada ou zerada, os dados são escritos apenas nos endereços ativos. Nas concretizações descritas, as escritas em endereços ilegais geram sempre falhas. dest=Vectorlndex(Start, Increment) A VectorWritelnt é uma instrução para gerar vetores de valores, que se ajustam monotonicamente pelo incremento de um valor de partida escalar especificado por Start. Essa instrução pode ser usada para inicializar variáveis de índices de loops, quando o ajuste de índice é constante.
Quando predicação ou zeramento é aplicado, o primeiro elemento ativo recebe o valor de partida, e o incremento é apenas aplicado aos elementos ativos subsequentes. Por exemplo: x = Vector I n dex(0,1); //x = {01 234567} dest=PropagatePostT(dest, src, pred) A instrução PropagatePostT propaga o valor de elementos ativos em src, como determinado por pred, a elementos inativos subsequentes de dest. Os elementos ativos, e quaisquer elementos inativos que precedem o primeiro elemento ativo, se mantêm inalterados em dest. A finalidade dessa instrução é pegar um valor, que é calculado condicionalmente, e propagar o valor calculado condicionalmente a iterações de loops subsequentes, como ocorre no código escalar equivalente. Por exemplo: Entry: dest ={89 A B C D E F} src ={12 3 4 5 6 7 8} pred ={0 0 1 1 0 0 1 0} Exit: dest ={89 A B 4 4 E 7} dest=PropagatePriorF(src, pred) A instrução PropagatePriorF propaga o valor dos elementos inativos de src, como determinado por pred. em elementos ativos subsequente em dest. Os elementos inativos são copiados de src em dest.
Se o primeiro elemento do predicado for ativo, então o último elemento de src é propagado àquela posição. Por exemplo: Entry: src ={12345678} pred ={10110010} Exit: dest ={82225668} dest=ConditionalStop(pred, deps) A instrução ConditionalStop avalia um vetor de predicados, pred, e identifica as transições entre os elementos predicados adjacentes, que implicam em dependências de dados, como especificado por deps. O deps de valores escalares pode ser imaginado como um conjunto de quatro bits, cada um dos quais indica uma possível transição entre elementos verdadeiros / falsos em pred, como processados da esquerda para a direita.
Esses bits transportam a presença da dependência indicada se ajustados, e garantem a ausência de dependência, se não forem ajustados. São: kTF — Implica em uma dependência conduzida por loop de uma iteração, para a qual o predicado é verdadeiro, para a iteração subsequente, para a qual o valor do predicado é falso. kFF — implica em uma dependência conduzida por loop de uma iteração, para a qual o predicado é falso, para a iteração subsequente, para a qual o valor do predicado é falso. kFT — Implica em uma dependência conduzida por loop de uma iteração, para a qual o predicado é falso, para a iteração subsequente, para a qual o valor do predicado é verdadeiro. kTT — Implica em uma dependência conduzida por loop de uma iteração, para a qual o predicado é verdadeiro, para a iteração subsequente, para a qual o valor do predicado é verdadeiro. A posição do elemento correspondente à iteração, que gera os dados, que são dependentes ao serem armazenados no vetor de destino, na posição de elemento correspondente à iteração que depende dos dados. Se não existe qualquer dependência, um valor de 0 é armazenado no vetor de destino naquele elemento. O vetor de índice de dependência resultante, ou DIV, contém um vetor de índices de posições de elementos, que representam as dependências. Por razões descritas abaixo, o primeiro elemento do vetor é o elemento de número 1 (em vez de 0).
Como um exemplo, considerar as dependências no loop do Exemplo 1 acima. Nesse loop, as transições entre as iterações verdadeiras e falsas da cláusula condicional representam uma dependência conduzida pelo loop, que requer uma quebra em paralelismo. Essa pode ser tratada por uso das seguintes instruções: p 1 = (t < FACTOR); // p1 = {00001100} p2 = ConditionalStop(p1, kTF|kFT); // p2 = {00004060} Em virtude da 4a iteração gerar os dados necessários, e a 5a iteração depender deles, um 4 é armazenado na posição 5 do vetor de saída p2 (que é o DIV). O mesmo se aplica para a 7a iteração, que depende de dados da 6a iteração. Outros elementos do DIV são ajustados em 0, para indicar a ausência de dependências. (Notar que neste exemplo o primeiro elemento do vetor é o elemento de número 1.) dest=GeneratePredicates(Pred, DIV) GeneratePredicates pega o vetor de índice de dependência, DIV, e gera os predicados correspondentes ao grupo seguinte de elementos, que podem ser processados com segurança em paralelo, supondo que o grupo prévio tenha sido processado, indicado por pred. Se nenhum elemento de pred está ativo, os predicados são gerados para o primeiro grupo de elementos, que podem ser processados com segurança em paralelo. Se Pred indicar que os elementos finais do vetor foram processados, então a instrução gera um vetor resultante de predicados inativos, indicando que nenhum elemento seja processado e o indicador ZF é ajustado. O indicador CF é ajustado para indica que o último elemento dos resultados está ativo.
Usando-se os valores no primeiro exemplo, o GeneratePredicates opera da seguinte maneira: Entry Conditions: // i2 = {00004060} p2 = 0; // p2 = { 0 0 0 0 0 0 0 0 } Loop2: p2 = GeneratePredicates(p2,i2); // p2’= {1 1 1 10000} CF = 0, ZF = 0 if(!PLAST()) goto Loop2 // p2”= {00001 1 00} CF = 0, ZF = Ο // p2’”= {00 0 00 0 1 1 } CF = 1, ZF = 0 De um predicado inicializado p2 de todos os zeros, o GeneratePredicates gera novos casos de p2, que dividem os cálculos de vetores subsequentes em três subvetores (isto é, p\ p" e p'"). Isso permite que o hardware processe o vetor em grupos, que evitam violação das dependências de dados do loop.
Na Figura 4, um diagrama ilustrando uma sequência de estados variáveis, durante execução escalar do loop no Exemplo 1, é mostrado. Mais particularmente, por uso de uma distribuição 50/50 aleatória da direção da expressão condicional, uma progressão dos estados variáveis do loop do Exemplo 1 é mostrada. Na Figura 4B, um diagrama ilustrando uma progressão de execução para o código de programa vetorizado macroescalar do loop do Exemplo 1 é mostrado. Nas Figuras 4A e 4B, os valores lidos de A[] são mostrados usando marcas hash de inclinação para o lado esquerdo, enquanto que os valores escritos para B[] são mostrados usando marcas hash de inclinação para o lado direito, e os valores para "r" ou "s" (dependendo no qual é alterado em uma determinada iteração) são mostrados usando um fundo sombreado. Observar que "r" nunca varia enquanto "s" está variando, e vice-versa.
Nada impede que todos os valores sejam lidos de A[| em paralelo ou escritos em B[] em paralelo, porque nenhum conjunto de valores participa na cadeia de dependência conduzida pelo loop. No entanto, para o cálculo de r e s, os elementos podem ser processados em paralelo apenas enquanto o valor da expressão condicional se mantém igual (isto é, execuções de verdadeiro ou falso). Esse modelo para a execução do código de programa para esse loop é mostrado na Figura 4B. Notar que o exemplo usa vetores tendo um comprimento de oito elementos. Quando do processamento da primeira instrução vetorial, a primeira iteração é conduzida sozinha (isto é, a unidade de execução vetorial 204 processa apenas o primeiro elemento vetorial), enquanto que as iterações 1-5 são processadas em paralelo pela unidade de execução vetorial 204, e depois as iterações 6-7 são processadas em paralelo pela unidade de execução vetorial 204.
Com referência às Figuras 5A e 5B, os diagramas ilustrando uma concretização da vetorização do código de programa são mostrados, A
Figura 5A ilustra o código-fonte original, enquanto que a Figura 5B ilustra o código vetorizado, representando as operações que podem ser executadas usando a arquitetura macroescalar. No código vetorizado da Figura 5B, o Loop 1 é o loop do código-fonte, enquanto que o Loop 2 é o loop de partição vetorial, que processa as subpartições vetoriais.
No exemplo, a disposição A[] é lida e comparada em vetores de comprimento integral (isto é, para um vetor de N elementos, N posições da disposição A[] são lidas de uma vez). O vetor i1 é o DIV, que controla a partição do vetor. A partição é determinada por monitoramento do predicado p1, para as transições entre falso e verdadeiro, que indicam dependências conduzidas pelo loop que devem ser observadas. O vetor de predicado p2 determina que elementos vão ser acionados a qualquer tempo. Nesse loop particular, p1 tem o mesmo valor em todos os elementos de qualquer subpartição vetorial; portanto, apenas o primeiro elemento da partição precisa ser checado para determinar que variável atualizar.
Após a variável "s" ser atualizada, a instrução PropagatePostT propaga o valor final, na partição ativa, para os elementos subsequentes no vetor. Na parte de cima do loop, a instrução PropagatePriorF copia o último valor de "s" da posição final do vetor por todos os elementos do vetor, em preparação para o passo seguinte. Notar que a variável "r" é propagada usando um método diferente, ilustrando as eficiências do uso da instrução PropagatePriorF em certos casos.
Especulação de software No exemplo anterior, as partições vetoriais, antes do início do loop de partição vetorial, puderam ser determinadas porque a decisão do fluxo de controle foi independente das dependências conduzidas pelo loop.
No entanto, este não é sempre o caso. Considerar os dois loops apresentados a seguir nos Exemplos 2A e 2B: EXEMPLO 2A: Loop de código de programa 1 j = 0; for (x=0; x<KSIZE; ++x) { if (A[x] < FACTOR) { j = A[x+j]; } B[x] = j; } EXEMPLO 2B: Loop de código de programa 2 j = 0; for (x=0; x<KSIZE; ++x) { if (A[x+j] < FACTOR) { j = A[x); } B[x] = j; } No Exemplo 2A, a decisão do fluxo de controle é independente da cadeia de dependência conduzida pelo loop, enquanto que no Exemplo 2B, a decisão do fluxo de controle é parte da cadeia de dependência conduzida pelo loop. Em algumas concretizações, o loop no Exemplo 2B pode provocar especulação de que o valor de "j" vai ficar inalterado, e compensar depois se esta previsão provar ser incorreta. Nessas concretizações, a especulação no valor de "j” não altera significativamente a vetorização do loop.
Em algumas concretizações, o compilador pode ser configurado para sempre prever nenhuma dependência de dados entre as iterações do loop. Nessas concretizações, no caso no qual existem dependências de dados quando da execução, o grupo de elementos ativos, processado em paralelo, pode ser reduzido para representar o grupo de elementos que podem ser processados em paralelo com segurança nesse momento.
Nessas concretizações, há pouca penalidade para uma previsão incorreta de mais paralelismo que de fato existe, porque nenhum paralelismo é de fato perdido (isto é, se necessário, as iterações podem ser processadas a um elemento por vez, em um modo não paralelo). Nessas concretizações, o grau de paralelismo efetivo é simplesmente reconhecido em um estágio posterior. dest=VectorReadlntFF(Base, Offset, pf) VectorReadlntFF é uma primeira variante do VectorReadlnt.
Essa instrução não gera uma falha, se pelo menos o primeiro elemento ativo for um endereço válido. Os resultados correspondentes a endereços inválidos são forçados a zero, e os sinalizadores pf são retornados, que podem ser usados para mascarar os predicados para instruções posteriores, que usam esses dados. Se o primeiro elemento ativo do endereço não estiver mapeado, essa instrução falha em permitir que um sistema de memória virtual no sistema computadorizado 100 (não mostrado) povoe uma página correspondente, garantindo, desse modo, que o processador 102 possa continuar a fazer um progresso para frente. dest=Remaining(Pred) A instrução Remaining avalia um vetor de predicados, Pred, e calcula os elementos remanescentes no vetor. Esse corresponde ao conjunto de predicados inativos seguintes ao último predicado ativo. Se não houver elementos ativos em Pred, um vetor de todos os predicados ativos é retornado. Igualmente, se Pred for um vetor de todos os predicados ativos, um vetor de predicados inativos é retornado. Por exemplo: Entry: pred ={00 1 0 1 000} Exit: dest ={0 000 0 1 1 1 } As Figuras 6A e 6B são diagramas ilustrando concretizações de um código de programa vetorizado exemplificativo. Mais particularmente, a amostra de código, mostrada na Figura 6A, é uma versão vetorizada do código no Exemplo 2A (como apresentado acima). A amostra de código mostrada na Figura 6B é uma versão vetorizada do código no Exemplo 2B.
Com referência à Figura 6B, a leitura de A[] e a comparação subsequente foram movimentadas para dentro do loop de partição vetorial. Desse modo, essas operações presumem (especulam) que o valor de "j" não varia.
Apenas após usar "j", é possível determinar se "j" pode variar o valor. Após "j" ser atualizado, os elementos vetorizados remanescentes são recomputados, se necessário, para iterar por todo o vetor. O uso da instrução Remaining, na amostra de código especulativo, permite que o programa determine que elementos ficam para ser processados no loop de partição vetorial, antes que o programa possa determinar o subgrupo desses elementos, que são, de fato, seguros processar (isto é, que não possuem dependências de dados não resolvidas).
Em várias concretizações, um suporte de leitura tolerante à falha é proporcionado. Desse modo, nessas concretizações, o processador 102 pode ler especulativamente dados da memória, usando endereços inválidos de uma instrução vetorial (por exemplo, VectorReadFF), em uma tentativa de carregar valores, que vão ser depois usados em cálculos. No entanto, por descoberta de que uma leitura inválida ocorreu, esses valores são finalmente descartados, e, portanto, não são adequados para corrigir o comportamento do programa. Em virtude dessas leituras poderem fazer referência à memória não existente ou protegida, essas concretizações podem ser configuradas para continuar a execução normal na presença de leitura inválida, mas com erro de dados irrelevante, da memória. (Notar que nas concretizações que suportam memória virtual, isso pode ter o benefício adicional da não paginação, até que haja certeza para que isso seja feito.) Nos loops de programa nas Figuras 6A e 6B, existe uma dependência conduzida pelo loop entre as iterações, nas quais a condição é verdadeira, e nas iterações subsequentes, independentemente do valor do predicado para as iterações posteriores. Isso é refletido nos parâmetros da instrução ConditionaiStop. O código de programa de amostra nas Figuras 6A e 6b realça as diferenças entre as partições vetoriais não especulativa e especulativa. Mais particularmente, no Exemplo 2A, a memória é lida e o predicado é calculado antes da ConditionaiStop. O loop de partição começa após a instrução ConditionaiStop. No entanto, no Exemplo 2B, a instrução ConditionaiStop é executada dentro do loop de partição, e serve para reconhecer as dependências que tornam as operações anteriores inválidas. Em ambos os casos, a instrução GeneratePredicates calcula os predicados que controlam que elementos são usados para o restante do loop de partição.
Dependências conduzidas pelo loop com base em memória Nos exemplos anteriores, o compilador foi capaz de estabelecer que nenhum nome alternativo de endereço existia quando da compilação.
No entanto, essas determinações são frequentemente difíceis ou impossíveis de fazer. O segmento de código, mostrado no Exemplo 3 abaixo, ilustra como as dependências conduzidas por loops pela memória (que podem incluir nome alternativo), são tratadas nas várias concretizações da arquitetura macroescalar. EXEMPLO 3: Loop de códigos de programas 3 for (x=0; x<KSIZE; ++x) { r = C[x]; s = D[x]; A[x] = A[r] + A[s]; } No segmento de código do EXEMPLO 3, o compilador não pode determinar se A[x] tem o nome alternativo de A[r] ou A[s]. No entanto, com a arquitetura macroescalar, o compilador simplesmente insere instruções que fazem com que o hardware cheque os riscos de memória quando da execução, e, consequentemente, divide o vetor durante a execução, para garantir um comportamento correto do programa. Uma dessas informações, que checa os riscos de memória, é a instrução CheckHazardP, que é descrita abaixo. dest = CheckHazardP (first, second, pred) A instrução CheckHazardP examina os dois vetores de um endereço (ou índices) de memória, correspondente às duas operações de memória, para dependências de dados potenciais pela memória. O "primeiro" vetor retém os endereços para a primeira operação de memória, e o "segundo" vetor retém os endereços para a segunda operação. O predicado "pred" indica ou controla que elementos do "segundo" vão ser operados. Na medida em que as iterações de loops escalares prosseguem adiante no tempo, os elementos vetoriais, representando as iterações sequenciais, aparecem da esquerda para a direita dentro dos vetores. A instrução CheckHazardP pode avaliar nesse contexto. A instrução pode calcular um DIV, representando riscos de memória entre o par correspondente de primeira e segunda operações de memória. A instrução pode avaliar corretamente os riscos de memória de escrever após ler escrever após escrever.
Do mesmo modo que com a instrução ConditionalStop descrita acima, a posição do elemento correspondente à iteração, que gera os dados, que são dependentes, pode ser armazenada no vetor de destino, na posição de elemento correspondente à iteração que é dependente dos dados. Se não existe qualquer dependência de dados, um zero pode ser armazenado no vetor de destino, na posição de elemento correspondente à iteração que não tem a dependência. Por exemplo: Entry: first ={23456789} second ={87654321} pred ={11111111} Exit: dest ={00003210} Como mostrado acima, o elemento 5 do primeiro vetor ("primeiro") e o elemento 3 do segundo vetor ("segundo") têm ambos acesso ao índice de disposição 6. Portanto, um 3 armazenado na posição 5 de DIV.
Igualmente, o elemento 6 dos primeiro e elemento 2 do segundo têm ambos acesso a uma posição de índice de disposição 7, fazendo com que um 2 seja armazenado na posição 6 do DIV, e assim por diante. Um zero é armazenado no DIV, quando não existe qualquer dependência de dados.
Em algumas concretizações, a instrução CheckHazardP pode considerar vários tamanhos de tipos de dados. No entanto, para clareza vai- se descrever a função da instrução usando apenas os tipos de índices de disposições. O acesso de memória no exemplo apresentado acima tem três riscos de memória. No entanto, nas concretizações descritas, apenas duas partições podem ser necessárias para processar com segurança as operações de memória associadas. Mais particularmente, a manipulação do primeiro risco na posição de elemento 3 torna as dependências subsequentes no elemento de número igual ou menos discutíveis. Por exemplo: . Entry Conditions: //DIV = {00003210} // p2 = {00000000} p2 = GeneratePredicates(p2,DIV); // p2 = { 1 1 1 1 0 0 0 0 } P2 = GeneratePredicates(p2, DIV) // p2 = { 0 0 0 0 1 1 1 1 } O método usado pelas concretizações descritas para analisar um DIV, para determinar quando um vetor deve ser decomposto, é mostrado abaixo em pseudocódigo. Em algumas concretizações, a unidade de execução vetorial 204 do processador 102 pode executar esse cálculo em paralelo. Por exemplo: List = <empty>; for (x=STARTPOS; x<VECLEN; ++x) { lf(DIV[x] in List) Breakfrom loop;
Else if(DIV[x]>0) Append <x> to List; } O vetor pode ser processado com segurança em paralelo pelo intervalo [STARTPOS.x], em que x é a posição na qual DIV[x] > 0. Isto é, de STARTPOS à (mas não incluindo a) posição x, em que STARTPOS se refere ao primeiro elemento vetorizado, após o conjunto de elementos processados de antemão. Se o conjunto de elementos processados previamente estiver vazio, então STARTPOS começa no primeiro elemento.
Em algumas concretizações, múltiplos DIVs podem ser gerados em código usando as instruções ConditionalStop e/ou CheckHazardP. A instrução GeneraIPredicates usa, no entanto, um único DIV para dividir o vetor. Há dois métodos para tratar essa situação: (1) os loops de partição podem ser aninhados; ou (2) os DIVs podem ser combinados e usados em um único loop de partição. Qualquer uma das abordagens produz resultados corretos, mas a abordagem ótima depende das características do loop em questão. Mais especificamente, quando múltiplos DIVs são previstos terem dependências, tais como quando o compilador não pode simplesmente determinar nomes alternativos em parâmetros de entrada, essas concretizações podem combinar múltiplos DIVs em um, reduzindo, desse modo, um código extra de partição. Por outro lado, nos casos em que, com uma expectativa de muitos riscos de memória percebidos, essas concretizações podem aninhar os loops de partição, extraindo, desse modo, o máximo paralelismo possível (considerando que existe a perspectiva de paralelismo adicional).
Em algumas concretizações, os DIVs podem ser combinados usando uma instrução VectorMax(A,B), como mostrado abaixo. 12 = CheckHazardP(a,c,pO); //i2 = {0 0 2 0 2 4 0 0} 13 = CheckHazardP(b,c,pO); //i3 = {0 0 1 3 3 0 0 0} ix = VactorMax(i2,i3); //ix = {0 0 2 3 3 4 0 0} Em virtude dos elementos de um DIV apenas poderem conter números inferiores à posição desse elemento, que representam as dependência em tempo anteriores, as dependências posteriores apenas servem para limitar ainda mais a partição, o que torna os valores mais baixos redundantes da perspectiva da instrução GeneraIPredicates. Desse modo, tirando-se o máximo de todos os DIVS, provoca-se, efetivamente, que a instrução GeneraIPredicates retorne para a interseção dos conjuntos de elementos, que podem ser processados com segurança em paralelo. A Figura 7 é um diagrama ilustrando uma concretização de um código de programa vetorizado. Mais particularmente, a amostra de código, mostrada na Figura 7, é uma versão vetorizada do código no Exemplo 3 (como apresentado acima). Com referência à Figura 7, não existe nenhuma ação de nome alternativo entre C[] ou D[] e A[], mas as operações de A[] podem ser também conhecidas de outro modo. Se o compilador for incapaz de excluir a denominação alternativa com C[] ou D[], o compilador pode gerar cheques de risco adicionais. Em virtude de não haver mais perigo de denominação alternativa nesse caso, as operações de leitura nas disposições C[] e D[] foram posicionadas fora do loop de partição vetorial, enquanto que as operações em A[] foram mantidas dentro do loop de partição. Se nenhuma denominação alternativa existe com A[], as partições mantêm o tamanho de vetor integral, e o loop de partição simplesmente falha sem promover iteração. No entanto, para as iterações nas quais uma denominação alternativa ocorre de fato, o loop de partição divide o vetor com relação às dependências de dados, garantindo, desse modo, a operação correta.
Na concretização mostrada no segmento de código da Figura 7, o cheque de risco é feito por todo o vetor de endereços. No caso geral, no entanto, é frequentemente necessário checar os riscos entre as operações de memória executadas condicionalmente. A instrução CheckHazardP pega um predicado, que indica que elementos na segunda operação de memória estão ativos. Se nem todos os elementos da primeira operação estão ativos, a própria instrução CheckHazardP pode ser predicada com um predicado de zeragem, correspondente àqueles elementos do primeiro item operável que estão ativos. (Notar que isso pode gerar resultados corretos para os casos nos quais a primeira operação de memória é predicada.) O segmento de código, no Exemplo 4 abaixo, ilustra um loop com um risco de memória na disposição E[], Na Figura 8, um diagrama ilustrando uma concretização de código de programa vetorizado exemplificativo é mostrado. Mais particularmente, a amostra de código mostrada na Figura 8 é uma versão macroescalar vetorizada do código no Exemplo 4 (apresentado acima). EXEMPLO 4: Loop de código de programa 4 j = 0; for (x=0; x<KSIZE; ++x) { f = A[x}; g = B[x]; if (f < FACTOR) { h = C[x]; j = E[h]; } if (g < FACTOR) { i = D[x]; } } Com referência à Figura 8, o loop vetorizado inclui os predicados p1 e p2, que indicam se a disposição E[] vai ser lida ou escrita, respectivamente. A instrução CheckHazardP checa os vetores de endereços (h e i) para riscos de memória. O parâmetro p2 é passado para o CheckHazardP como o predicado controlando a segunda operação de memória (a escrita). Desse modo, a CheckHazardP identifica um ou mais riscos de memória entre as leituras não condicionais e as escritas condicionais predicadas em p2. O resultado de CheckHazardP é predicado zero em p1. Isso coloca zeros no DIV(ix) para as posições de elementos, que não vão ser lidas de E[], Deve-se relembrar que um zero indica ausência de risco. Desse modo, o resultado, armazenado em x, é um DIV, que representa os riscos entre as leituras condicionais predicadas em p1 e as escritas condicionais predicadas em p2. Isso é tornado possível porque as condições de ausência de risco são representadas com um zero no DIV.
Deve-se notar que nas concretizações mencionadas acima, para checar riscos de memória, a instrução CheckHazardIP foi usada. Como descrito acima, a instrução CheckHazardP considera um predicado como um parâmetro, que controla que elementos do segundo vetor são operados nele.
No entanto, em outras concretizações, outros tipos de instruções CheckHazard podem ser usados. Por exemplo, como usada em vários exemplos apresentados abaixo, uma instrução CheckHazardP, que omite o parâmetro do predicado, pode ser usada, dependendo da implementação do código desejado específico. Em uma concretização, essa versão da instrução CheckHazard pode simplesmente ser operada condicionalmente nos dois vetores de entrada. Independentemente de que versão da instrução CheckHazardl é empregada, deve-se notar que do mesmo modo que com a instrução Macroscalar, que suporta a predicação e/ou zeragem do resultado, se ou não um determinado elemento de um vetor de resultado é modificado por execução da instrução CheckHazard, ela pode ser controlada separadamente por uso de um vetor de predicado ou vetor de zeragem, como descrito acima. Isto é, o parâmetro do predicado da instrução CheckHazard controla um aspecto diferentes de execução de instrução do que o vetor de predicado / zeragem geral descrito acima.
Detecção de um primeiro desvio para trás, após uma instrução de geração de predicado Como descrito acima, quando da vetorização de um segmento de código, um loop de partição vetorial pode ser usado no código de programa, que executa a vetorização, para tratar corretamente possíveis dependências conduzidas por loops, tais como, por exemplo, riscos de memória. Nesse código de programa, uma instrução Macroscalar, tal como a instrução CheckHazard (descrita acima), por exemplo, pode gerar um DIV, que pode ser depois usado pela instrução Macroscalar GeneratePredicates, que é parte do loop de partição vetorial. Além disso, o loop de partição vetorial usa um desvio para trás, como parte do loop. Como mencionado acima, se esse desvio para trás for previsto com precisão, o desempenho do processador pode ser mantido. No entanto, se esse desvio for mal previsto (que é em muitos casos), o desempenho pode sofrer. Desse modo, pode ser benéfico em muitos casos eliminar a previsão do desvio e esperar que o DIV fique disponível. Isto é, em alguns casos, a penalidade de interromper efetivamente a execução, até que o DIV esteja disponível, pode ser inferior à penalidade de prever incorretamente o desvio, que forma o limite de um loop de partição vetorial.
Como um exemplo particular de um loop de partição vetorial, que pode se beneficiar das técnicas descritas no presente relatório descritivo, um exemplo de um segmento de código, que gera um histograma A[], representando itens em B[], é mostrado no Exemplo 5 abaixo.
Exemplo 5 for (x=0; x<K; ++x) A[B[x]] = A[B[x]]+ 1;
Quando um compilador vetoriza o segmento de código do Exemplo 5, deve-se reconhecer se quaisquer elementos em um vetor de B[] contêm o mesmo valor. Se isso não for feito, o código não vai reconhecer que elementos de A[] vão ser modificados, afetando as modificações posteriores de A[j no mesmo vetor. Um segmento de código macroescalar, que inclui um loop de partição vetorial, que trata quaisquer dependências conduzidas por loops, no segmento de código do Exemplo 5, é mostrado no Exemplo 6.
Exemplo 6 p1 = FALSE; VO = VectorRead(B,x);
V2 = CheckHazard(VO,VO); // calculate DIV
PartLoop: ρ1 = GeneratePredicates(p1, V2); p1: V1 = VectorRead(A,VO); p1: V1 = Vectorlncr(V1); p1: VectoíWrite(A,V1);
Branch on Carry-Clear to PartLoopNo segmento de código do Exemplo 6, a instrução CheckHazard avalia os endereços de memória, para detectar os riscos de memória (produzindo o DIV armazenado em V2), e a instrução GeneratePredicates usa essas informações para calcular um predicado, que controla o número de elementos que podem ser processados com segurança em paralelo. Se todo o vetor não puder ser processado com segurança em paralelo, o loop de partição vetorial (PartLoop) é iterado, até que um vetor integral tenha sido processado (o que é indicado por um dos indicadores do processador, tal como o indicador Carry sendo ajustado).
Ainda que não haja de fato qualquer risco de memória em um loop, é frequentemente o caso que um compilador não pode determinar isso conclusivamente quando da compilação. Desse modo, todo o vetor é frequentemente processado em paralelo durante a execução, mesmo que o compilador seja forçado a emitir um loop de partição vetorial. Os mecanismos de previsão de desvio convencionais podem operar eficientemente nesse caso, prevendo que o loop não vai ser nunca iterado, e o desempenho integral é mantido.
No entanto, no caso no qual o vetor é frequentemente dividido, os mecanismos de previsão de desvio convencionais frequentemente fazem más previsões, afetando adversamente o desempenho. Isso pode ser prejudicial, em virtude da natureza dos loops de partição vetorial. Um loop de partição vetorial vai conter, tipicamente, uma cadeia de instruções, que são dependentes em série entre si. O desempenho dessa seção de código pode ser, portanto, limitado pelo código serial, mesmo se a previsão de desvio seja perfeita. Como descrito acima, há uma penalidade de desempenho para a má previsão de desvios, e a parte superior para uma boa previsão é limitada, devido à natureza do loop. Além do mais, nos casos nos quais o loop de partição é de fato iterado mais de uma vez, pode ser iterado apenas um número limitado de vezes (usualmente, apenas uns poucos segundos).
Isso pode levar, nesses casos, a altas taxas de má previsão, o que afeta adversa mente ambos os desempenho e potência. Desse modo, a precisão de previsão de desvio do loop de partição vetorial pode ser criticamente importante. Consequentemente, como descrito adicionalmente abaixo, ao detectar-se uma primeira instrução de controle de fluxo para trás, que se segue a uma instrução de geração de predicado, a previsão dessa instrução de controle de fluxo pode ser eliminada, até que o DIV fique disponível, dependendo de uma indicação recebida da precisão de previsão.
Na Figura 9, um fluxograma, ilustrando a operação de uma concretização do processador da Figura 2, durante execução de instruções de programa, que formam um loop de partição vetorial, é mostrado. Com referência coletiva às Figuras 2 a 9, e começando no bloco 901 da Figura 9, a unidade de previsão de desvio 210 detecta uma primeira instrução de desvio para trás condicional, que se segue a uma instrução de geração de predicado. Mais particularmente, em uma concretização, a instrução de desvio para trás condicional pode ser uma instrução de desvio condicional, que se desvia a um endereço-alvo, que precede a instrução de desvio (por exemplo, para iniciar o loop de partição vetorial), e que se desvia quando uma sentença condicional é avaliada como verdadeira. Na concretização mostrada no Exemplo 6, a sentença condicional é dependente do código de condição clara conduzido. Além disso, a instrução de geração de predicado pode ser uma instrução Macroscalar GeneratePredicates, que, como descrito acima, pode criar um vetor de predicado, que é dependente de um vetor de dependência, tal como o DIV. Em uma implementação, a instrução de desvio para trás, que é detectada após a instrução GeneratePredicates, pode ser uma instrução de desvio, que é baseada em um código condicional, que é ajustado pela instrução Macroscalar CheckHazard ou pela instrução Macroscalar ConditionalStop, que são ambas descritas acima em detalhes. Deve-se notar que embora a instrução Macroscalar CheckHazard seja usada em conjunto com o Exemplo 6, considera-se que outras versões da instrução Macroscalar CheckHazard, tal como a instrução CheckHazard predicada, por exemplo, podem ser usada no lugar dela.
Como descrito acima, a unidade de previsão de desvio 210 pode gerar e manter informações para várias previsões de desvio. Desse modo, a unidade de previsão de desvio 210 pode ser configurada para gerar e/ou receber uma indicação da precisão de previsão da instrução de desvio para trás (bloco 903). Em uma implementação, a indicação de previsão pode ser um valor de precisão, que indica a precisão, enquanto que, em outras implementações, a indicação de precisão pode ser um sinal binário, que é indicativo de se ou não a precisão de previsão satisfaz um limiar de precisão predeterminado.
Em várias concretizações, o limiar, que determina se um determinado desvio é ou não previsto com precisão, para fins de eliminar a previsão, pode ser um valor implícito ou codificado por hardware, um valor que pode ser modificado por operação de programação em hardware ou de modo de teste do método, ou um valor que pode ser modificado livremente por software. O limiar pode ser fixado variavelmente ou deixado variar dinamicamente em consequência do comportamento durante a execução.
Em algumas concretizações, diferentes valores de limiar podem ser mantidos separadamente para diferentes casos de desvios, por exemplo, como parte da estatística associada com um determinado desvio em uma tabela de história de desvios, mantida pela unidade de previsão de desvio 210. Alternativamente, em vez de armazenar implicitamente um limiar para diferentes desvios, a unidade de previsão de desvio 210 pode simplesmente armazenar uma indicação binária de se um determinado desvio é ou não previsto com precisão, como mencionado acima.
Em uma concretização, em resposta à determinação de que a precisão de previsão da instrução de desvio para trás não satisfaz o limiar predeterminado, a unidade de previsão de desvio 210 pode ser configurada para eliminar a previsão, até que o DIV esteja disponível (bloco 905). Mais particularmente, uma vez que as informações do DIV indicam o número de vezes exato que o loop vai ser iterado, em uma concretização, a unidade de previsão de desvio 210 pode ser configurada para usar as informações do DIV para prever quaisquer desvios futuros. Por exemplo, o DIV pode indicar que um vetor pode requerer três passagens pelo loop. Usando essas informações, a unidade de previsão de desvio 210 pode evitar previsão incorreta do desvio para trás, porque o número de iterações do loop pode ser conhecido do DIV com toda a certeza.
Em uma implementação, a unidade de previsão de desvio 210 pode interromper o encadeamento, enquanto aguarda pelo DIV, impedindo, desse modo, que quaisquer instruções adicionais sejam recuperadas. Em outra implementação, a unidade de previsão de desvio 210 pode fazer com que o processador 102 mude os contextos, enquanto aguardando que o DIV
esteja disponível. Em outra concretização, quando as informações do DIV estão disponíveis, a unidade de previsão de desvio 210 pode enviar uma notificação de recuperação de loop para a unidade de recuperação 201. Em resposta à indicação, a unidade de recuperação 201 pode usar as informações do DIV, para carregar as instruções para cada iteração do loop de partição vetoríal.
Deve-se notar que a espera para que o DIV fique disponível, pode ser substancialmente equivalente à espera para que o código condicional, que controla o desvio, fique disponível, uma vez que são ambos gerados pela mesma instrução. Isso permite que a unidade de recuperação 201 do processador 102 restabeleça imediatamente a busca, com base no código condicional, ainda que possa levar vários ciclos para analisar o DIV e, consequentemente, configurar a unidade de previsão de desvio 210. Isso pode minimizar a interrupção de encadeamento, no caso quando o encadeamento é interrompido para esperar pelo DIV. Deve-se também notar que, em uma concretização, a precisão da previsão de desvio pode continuar a ser rastreada, ainda que o desvio seja eliminado e as informações do DIV sejam usadas. Isso pode permitir que a unidade de previsão de desvio 210 detecte quando a precisão da previsão satisfaz o limiar, e varie o seu modo operacional para prever o desvio, em vez de esperar que o DIV fique disponível. Isto é, a decisão de eliminar a previsão de um determinado desvio, com base em uma má previsão, pode ser reversível posteriormente, se a precisão for aperfeiçoada.
Embora as concretizações apresentadas acima tenham sido descritas em detalhes consideráveis, várias variações e modificações vão ficar evidentes para aqueles versados na técnica, uma vez que a descrição apresentada acima seja considerada inteiramente. Intenciona-se que as reivindicações apresentadas a seguir sejam interpretadas para abranger todas essas variações e modificações. Intenciona-se ainda que aquelas compatíveis das reivindicações apresentadas a seguir podem ser praticadas em qualquer combinação adequada, e que essas combinações são intencionadas especificamente para que sejam descritas explicitamente no presente relatório descritivo.
Um dispositivo processador pode empregar qualquer meio ade- quado para executar quaisquer das etapas, operações ou funções do méto- do descritas no presente relatório descritivo, incluindo quaisquer das etapas das reivindicações do método listadas abaixo, em qualquer combinação a- dequada. Desse modo, por exemplo, um dispositivo processador, que exe- cuta as etapas, operações ou funções descritas no presente relatório descri- tivo, é considerado como estando dentro do âmbito dessa descrição, mesmo se os elementos estruturais do processadores diferirem dos elementos estru- turais exemplificativos descritos no presente relatório descritivo.

Claims (20)

1. Método, compreendendo: detectar uma primeira instrução de desvio condicional que segue a uma instrução de geração de predicado, em que a primeira instrução de desvio condicional se desvia para trás, quando seguida, e em que a instru- ção de geração de predicado, quando executada, gera um vetor de predica- do dependente de um vetor de dependência, em que cada elemento do vetor de dependência inclui um índice, que indica se existe uma dependência de dados entre os elementos de uma instrução vetorial; receber uma indicação de uma precisão de previsão da primeira instrução de desvio condicional; e em resposta a uma determinação, com base na indicação da precisão de previsão, de que a precisão de previsão da primeira instrução de desvio condicional não satisfaz um valor de limiar, eliminar a previsão da primeira instrução de desvio condicionai, até que o vetor de dependência, do qual a instrução de geração de predicado depende, esteja disponível.
2. Método de acordo com a reivindicação 1, compreendendo a- inda, em resposta à detecção de que o vetor de dependência está disponí- vel, prever a primeira instrução de desvio condicional usando informações de dependência de dados indicadas no vetor de dependência.
3. Método de acordo com a reivindicação 1, em que a instrução de geração de predicado é uma instrução GeneratePredicates macroescalar.
4. Método de acordo com a reivindicação 1, em que eliminar a previsão da primeira instrução de desvio condicional inclui prever a primeira instrução de desvio condicional e descartar a previsão.
5. Método de acordo com a reivindicação 1, em que eliminar a previsão da primeira instrução de desvio condicional inclui impedir que novas instruções sejam executadas, até que o vetor de dependência esteja dispo- nível.
6. Método de acordo com a reivindicação 1, em que eliminar a previsão da primeira instrução de desvio condicional inclui descartar uma previsão gerada de antemão na qual o fluxo de controle de execução de ins- truções de programa não é alterado, por execução da primeira instrução de desvio condicional.
7. Método de acordo com a reivindicação 1, compreendendo a- inda usar o vetor de dependência, quando este fica disponível, para determi- nar um número de vezes em que o fluxo de controle de execução de instru- ções de programa é alterado, responsivo a cada execução da primeira ins- trução de desvio condicional.
8. Método de acordo com a reivindicação 1, em que eliminar a previsão da primeira instrução de desvio condicional inclui impedir que novas instruções sejam recuperadas em um encadeamento de execução, até que o vetor de dependência esteja disponível.
9. Método de acordo com a reivindicação 1, em que eliminar a previsão da primeira instrução de desvio condicional inclui impedir que novas instruções sejam executadas, até que o vetor de dependência esteja dispo- nível.
10. Processador, compreendendo: um ou mais meios para executar as etapas de acordo com qual- quer uma das reivindicações 1 a 9.
11. Processador, compreendendo: uma unidade de recuperação para recuperar, seletivamente, ins- truções para execução; e uma unidade de previsão acoplada à unidade de recuperação e configurada para detectar uma primeira instrução de desvio condicional que segue a uma instrução de geração de predicado, em que a primeira instru- ção de desvio condicional se desvia para trás, quando seguida, e em que a instrução de geração de predicado, quando executada, gera um vetor de predicado dependente de um vetor de dependência, em que cada elemento do vetor de dependência inclui um índice, que indica se existe uma depen- dência de dados entre os elementos de uma instrução vetorial, em que a unidade de previsão é configurada para gerar uma in- dicação de uma precisão de previsão da primeira instrução de desvio condi- cional; e em que a unidade de previsão é configurada para, em resposta à determinação de que a precisão de previsão da primeira instrução de des- vio condicional não satisfaz um valor de limiar, eliminar a previsão da primei- ra instrução de desvio condicional, até que o valor de dependência, do qual depende a instrução de geração de predicado, esteja disponível.
12. Processador de acordo com a reivindicação 11, em que a u- nidade de previsão é configurada para prever a primeira instrução de desvio condicional, em resposta ao recebimento de informações de dependência de dados indicadas no vetor de dependência.
13. Processador de acordo com a reivindicação 11, em que a u- nidade de recuperação é configurada para protelar, enquanto aguarda que o vetor de dependência esteja disponível.
14. Processador de acordo com a reivindicação 11, compreen- dendo ainda uma unidade de execução, acoplada à unidade de recuperação e configurada para desviar contextos, enquanto aguarda que o vetor de de- pendência esteja disponível.
15. Processador de acordo com a reivindicação 11, em que a u- nidade de previsão é configurada para gerar uma previsão para o primeiro desvio condicional, e em que para eliminar a previsão do primeiro desvio condicional, a unidade de previsão é configurada para descartar a previsão da primeira instrução de desvio condicional, em resposta à determinação de que a precisão de previsão da primeira instrução de desvio condicional não satisfaz o valor de limiar.
16. Processador de acordo com a reivindicação 11, em que a primeira instrução de desvio condicional define um limite de um loop de ins- truções, e em que o vetor de dependência indica um número exato de vezes em que o loop de instruções vai ser executado.
17. Processador de acordo com a reivindicação 16, em que, em resposta à detecção de que o vetor de dependência está disponível, a uni- dade de previsão é configurada para proporcionar uma indicação de recupe- ração de loop, e em que a unidade de recuperação é configurada para recu- perar instruções para cada iteração do loop de instruções, em resposta ao recebimento da indicação de recuperação de loop.
18. Processador de acordo com a reivindicação 11, em que, pa- ra eliminar a previsão da primeira instrução de desvio condicional, a unidade de previsão é configurada ainda para impedir a execução de novas instru- ções, até que o vetor de dependência esteja disponível.
19. Processador de acordo com a reivindicação 11, em que a instrução de geração de predicado é uma instrução GeneratePredicates ma- croescalar.
20. Sistema, compreendendo: uma memória configurada para armazenar instruções de pro- grama; e uma ou mais ocorrências do processador como definido em qualquer uma das reivindicações 11 a 19 acoplado à memória.
BRBR102013007865-4A 2012-04-02 2013-04-01 Aperfeiçoamento de desempenho de loops de partição vetorial BR102013007865A2 (pt)

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
US13/437,482 US9116686B2 (en) 2012-04-02 2012-04-02 Selective suppression of branch prediction in vector partitioning loops until dependency vector is available for predicate generating instruction

Publications (1)

Publication Number Publication Date
BR102013007865A2 true BR102013007865A2 (pt) 2015-07-07

Family

ID=48044642

Family Applications (1)

Application Number Title Priority Date Filing Date
BRBR102013007865-4A BR102013007865A2 (pt) 2012-04-02 2013-04-01 Aperfeiçoamento de desempenho de loops de partição vetorial

Country Status (8)

Country Link
US (1) US9116686B2 (pt)
EP (1) EP2648090A3 (pt)
JP (1) JP2013254484A (pt)
KR (1) KR101511837B1 (pt)
CN (1) CN103383640B (pt)
BR (1) BR102013007865A2 (pt)
TW (1) TWI512617B (pt)
WO (1) WO2013151861A1 (pt)

Families Citing this family (20)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US9323531B2 (en) * 2013-03-15 2016-04-26 Intel Corporation Systems, apparatuses, and methods for determining a trailing least significant masking bit of a writemask register
US10241793B2 (en) 2013-03-15 2019-03-26 Analog Devices Global Paralleizing loops in the presence of possible memory aliases
GB2519107B (en) 2013-10-09 2020-05-13 Advanced Risc Mach Ltd A data processing apparatus and method for performing speculative vector access operations
GB2519108A (en) 2013-10-09 2015-04-15 Advanced Risc Mach Ltd A data processing apparatus and method for controlling performance of speculative vector operations
US10223113B2 (en) 2014-03-27 2019-03-05 Intel Corporation Processors, methods, systems, and instructions to store consecutive source elements to unmasked result elements with propagation to masked result elements
WO2015145193A1 (en) * 2014-03-28 2015-10-01 Intel Corporation Processors, methods, systems, and instructions to store source elements to corresponding unmasked result elements with propagation to masked result elements
US10289417B2 (en) 2014-10-21 2019-05-14 Arm Limited Branch prediction suppression for blocks of instructions predicted to not include a branch instruction
US20160179550A1 (en) * 2014-12-23 2016-06-23 Intel Corporation Fast vector dynamic memory conflict detection
GB2540941B (en) * 2015-07-31 2017-11-15 Advanced Risc Mach Ltd Data processing
GB2545248B (en) * 2015-12-10 2018-04-04 Advanced Risc Mach Ltd Data processing
GB2548602B (en) * 2016-03-23 2019-10-23 Advanced Risc Mach Ltd Program loop control
GB2549737B (en) * 2016-04-26 2019-05-08 Advanced Risc Mach Ltd An apparatus and method for managing address collisions when performing vector operations
GB2571527B (en) * 2018-02-28 2020-09-16 Advanced Risc Mach Ltd Data processing
US11860996B1 (en) 2018-04-06 2024-01-02 Apple Inc. Security concepts for web frameworks
US10915322B2 (en) * 2018-09-18 2021-02-09 Advanced Micro Devices, Inc. Using loop exit prediction to accelerate or suppress loop mode of a processor
US11403256B2 (en) * 2019-05-20 2022-08-02 Micron Technology, Inc. Conditional operations in a vector processor having true and false vector index registers
US11327862B2 (en) 2019-05-20 2022-05-10 Micron Technology, Inc. Multi-lane solutions for addressing vector elements using vector index registers
US11340904B2 (en) 2019-05-20 2022-05-24 Micron Technology, Inc. Vector index registers
US11507374B2 (en) 2019-05-20 2022-11-22 Micron Technology, Inc. True/false vector index registers and methods of populating thereof
CN115113934B (zh) * 2022-08-31 2022-11-11 腾讯科技(深圳)有限公司 指令处理方法、装置、程序产品、计算机设备和介质

Family Cites Families (31)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5228131A (en) * 1988-02-24 1993-07-13 Mitsubishi Denki Kabushiki Kaisha Data processor with selectively enabled and disabled branch prediction operation
US5903750A (en) 1996-11-20 1999-05-11 Institute For The Development Of Emerging Architectures, L.L.P. Dynamic branch prediction for branch instructions with multiple targets
JPH1185515A (ja) 1997-09-10 1999-03-30 Ricoh Co Ltd マイクロプロセッサ
US6988183B1 (en) 1998-06-26 2006-01-17 Derek Chi-Lan Wong Methods for increasing instruction-level parallelism in microprocessors and digital system
US6353883B1 (en) 1998-08-04 2002-03-05 Intel Corporation Method and apparatus for performing predicate prediction
EP1122639A3 (en) * 1998-08-24 2002-02-13 Advanced Micro Devices, Inc. Mechanism for load block on store address generation and universal dependency vector/queue entry
JP2000322257A (ja) 1999-05-10 2000-11-24 Nec Corp 条件分岐命令の投機的実行制御方法
US7159099B2 (en) 2002-06-28 2007-01-02 Motorola, Inc. Streaming vector processor with reconfigurable interconnection switch
US7571302B1 (en) 2004-02-04 2009-08-04 Lei Chen Dynamic data dependence tracking and its application to branch prediction
US20060168432A1 (en) 2005-01-24 2006-07-27 Paul Caprioli Branch prediction accuracy in a processor that supports speculative execution
US7587580B2 (en) 2005-02-03 2009-09-08 Qualcomm Corporated Power efficient instruction prefetch mechanism
US20070288732A1 (en) * 2006-06-08 2007-12-13 Luick David A Hybrid Branch Prediction Scheme
JPWO2008029450A1 (ja) 2006-09-05 2010-01-21 富士通株式会社 分岐予測ミスリカバリ機構を有する情報処理装置
US7627742B2 (en) 2007-04-10 2009-12-01 International Business Machines Corporation Method and apparatus for conserving power by throttling instruction fetching when a processor encounters low confidence branches in an information handling system
US8006070B2 (en) 2007-12-05 2011-08-23 International Business Machines Corporation Method and apparatus for inhibiting fetch throttling when a processor encounters a low confidence branch instruction in an information handling system
US8271832B2 (en) 2008-08-15 2012-09-18 Apple Inc. Non-faulting and first-faulting instructions for processing vectors
US8984262B2 (en) 2008-08-15 2015-03-17 Apple Inc. Generate predicates instruction for processing vectors
US20110035568A1 (en) 2008-08-15 2011-02-10 Apple Inc. Select first and select last instructions for processing vectors
US8417921B2 (en) 2008-08-15 2013-04-09 Apple Inc. Running-min and running-max instructions for processing vectors using a base value from a key element of an input vector
US8793472B2 (en) 2008-08-15 2014-07-29 Apple Inc. Vector index instruction for generating a result vector with incremental values based on a start value and an increment value
US20100325399A1 (en) 2008-08-15 2010-12-23 Apple Inc. Vector test instruction for processing vectors
US20110283092A1 (en) 2008-08-15 2011-11-17 Apple Inc. Getfirst and assignlast instructions for processing vectors
US8356159B2 (en) 2008-08-15 2013-01-15 Apple Inc. Break, pre-break, and remaining instructions for processing vectors
US8447956B2 (en) 2008-08-15 2013-05-21 Apple Inc. Running subtract and running divide instructions for processing vectors
US8650383B2 (en) 2008-08-15 2014-02-11 Apple Inc. Vector processing with predicate vector for setting element values based on key element position by executing remaining instruction
US8959316B2 (en) 2008-08-15 2015-02-17 Apple Inc. Actual instruction and actual-fault instructions for processing vectors
US20100115233A1 (en) 2008-10-31 2010-05-06 Convey Computer Dynamically-selectable vector register partitioning
JP5387819B2 (ja) 2008-12-26 2014-01-15 日本電気株式会社 分岐予測の信頼度見積もり回路及びその方法
US8521996B2 (en) 2009-02-12 2013-08-27 Via Technologies, Inc. Pipelined microprocessor with fast non-selective correct conditional branch instruction resolution
US9176737B2 (en) 2011-02-07 2015-11-03 Arm Limited Controlling the execution of adjacent instructions that are dependent upon a same data condition
US9268569B2 (en) 2012-02-24 2016-02-23 Apple Inc. Branch misprediction behavior suppression on zero predicate branch mispredict

Also Published As

Publication number Publication date
TWI512617B (zh) 2015-12-11
WO2013151861A1 (en) 2013-10-10
CN103383640A (zh) 2013-11-06
KR101511837B1 (ko) 2015-04-13
KR20130112009A (ko) 2013-10-11
EP2648090A2 (en) 2013-10-09
CN103383640B (zh) 2016-02-10
US9116686B2 (en) 2015-08-25
US20130262833A1 (en) 2013-10-03
TW201403470A (zh) 2014-01-16
JP2013254484A (ja) 2013-12-19
EP2648090A3 (en) 2017-11-01

Similar Documents

Publication Publication Date Title
BR102013007865A2 (pt) Aperfeiçoamento de desempenho de loops de partição vetorial
US8271832B2 (en) Non-faulting and first-faulting instructions for processing vectors
US8359461B2 (en) Running-shift instructions for processing vectors using a base value from a key element of an input vector
US8793472B2 (en) Vector index instruction for generating a result vector with incremental values based on a start value and an increment value
US9268569B2 (en) Branch misprediction behavior suppression on zero predicate branch mispredict
US8959316B2 (en) Actual instruction and actual-fault instructions for processing vectors
US9298456B2 (en) Mechanism for performing speculative predicated instructions
US9400651B2 (en) Early issue of null-predicated operations
US8464031B2 (en) Running unary operation instructions for processing vectors
US8984262B2 (en) Generate predicates instruction for processing vectors
US8650383B2 (en) Vector processing with predicate vector for setting element values based on key element position by executing remaining instruction
US9182959B2 (en) Predicate count and segment count instructions for processing vectors
US20110035568A1 (en) Select first and select last instructions for processing vectors
US20110276782A1 (en) Running subtract and running divide instructions for processing vectors
US20100325399A1 (en) Vector test instruction for processing vectors
US20110283092A1 (en) Getfirst and assignlast instructions for processing vectors
US9389860B2 (en) Prediction optimizations for Macroscalar vector partitioning loops
US9715386B2 (en) Conditional stop instruction with accurate dependency detection
US9311094B2 (en) Predicting a pattern in addresses for a memory-accessing instruction when processing vector instructions
US20130318332A1 (en) Branch misprediction behavior suppression using a branch optional instruction
US9390058B2 (en) Dynamic attribute inference

Legal Events

Date Code Title Description
B03A Publication of a patent application or of a certificate of addition of invention [chapter 3.1 patent gazette]
B06F Objections, documents and/or translations needed after an examination request according [chapter 6.6 patent gazette]
B06U Preliminary requirement: requests with searches performed by other patent offices: procedure suspended [chapter 6.21 patent gazette]
B11B Dismissal acc. art. 36, par 1 of ipl - no reply within 90 days to fullfil the necessary requirements