Processador vetorial

Um processador de vetor, ou processador de matriz, é uma unidade de processamento central (CPU) que implementa um conjunto de instruções que contém instruções que operam sobre matrizes unidimensionais de dados chamados de vetores. Isto está em contraste com um processador escalar, cujas instruções operam em itens de dados individuais. Os processadores vetoriais podem melhorar muito o desempenho em determinadas cargas de trabalho, nomeadamente a simulação numérica e tarefas similares. Computadores com processadores vetoriais apareceram no início de 1970 e dominaram os projetos de supercomputadores entre a década de 70 e 90. A rápida queda na relação preço-desempenho de projetos de microprocessadores convencionais levou à morte do supercomputador vetorial logo após o ano de 1990.

"Processador de matriz" não deve ser confundido com o processamento da Matriz.

Hoje, a maioria das CPUs implementam arquiteturas que apresentam instruções para uma forma de processamento vetorial em vários conjuntos de dados, normalmente conhecidos como SIMD (Single Instruction Multiple Data). Exemplos comuns incluem VIS, MMX, SSE, AltiVec e AVX. Técnicas de processamento vetorial também são encontrados no hardware de jogos de vídeo game e aceleradores gráficos. Em 2000, a IBM, Toshiba e Sony colaboraram para criar o processador Cell, que consiste em um processador escalar e oito processadores vetoriais, que encontrou uso na Sony PlayStation 3, entre outras aplicações.

Outros projetos de CPU podem incluir algumas instruções múltiplas para processamento vetorial em vários conjuntos de dados, geralmente conhecidas como MIMD (Instrução Múltipla, Multiple Data) e realizados com VLIW. Estes projetos são geralmente dedicados a uma aplicação específica e que normalmente não são comercializados para a informática em geral. No processador VLIW / vetor Fujitsu FR-V ambas as tecnologias são combinadas.

História

editar

O desenvolvimento de processadores vetoriais começou no início dos anos 60 na Westinghouse Solomon Projetos. O Objetivo da Solomon foi aumentar drasticamente o desempenho da matemática usando um Grande número de processadores simples com controle em um único mestre CPU. A CPU era alimentada com uma única instrução comum a todas as unidades de lógica aritmética(ULAs), mas com um ponto de dados diferente para cada um deles para trabalhar. Isto permitiu que a máquina Solomon aplicasse um único algoritmo para um grande conjunto de dados , alimentado na forma de uma matriz.

Em 1962, a Westinghouse cancelou o projeto, mas o esforço foi reiniciado na Universidade de Illinois como o ILLIAC IV. A sua versão do projeto originalmente foi criada para uma uma GFLOPS máquina com 256 ULAs, mas, quando finalmente foi entregue em 1972, tinha apenas 64 ULAs e podia chegar a apenas 100 ou 150 MFLOPS. No entanto, mostrou que o conceito básico era o som, e, quando usado em aplicações intensivas de dados, tais como dinâmica de fluidos computacionais, o ILLIAC foi a máquina mais rápida do mundo. A abordagem ILLIAC de usar separado ULAs para cada elemento de dados não é comum para projetos posteriores, e é muitas vezes referida numa categoria separada, massivamente paralela de computação.

Um computador para operações com funções foi apresentado e desenvolvido por Kartsev em 1967.[1]

Supercomputadores

editar

A primeira implementação de sucesso do processamento vetorial foi Control Data Corporation STAR-100 e a Texas Instruments Advanced Computer Científica (ASC). A ASC básica usava uma arquitetura de pipeline que apoiou os cálculos vetoriais, com desempenho máximo atingindo cerca de 20 MFlops, facilmente alcançados ao processar vetores longos. As configurações expandidas suportavam 2 tubos ou 4 tubos, com um ganho de desempenho correspondente de duas ou quatro vezes mais. A largura de banda de memória era suficiente para suportar esses modos expandidos. Esses cálculos foram utilizados no computador CDC 7600, no entanto, a máquina levava um tempo considerável para decodificar as instruções vetoriais e se preparando para executar o processo, o que exigia dados muito específicos.

O primeiro vetor totalmente explorado foi em 1976 pelo famoso Cray-1. Em vez de deixar os dados na memória o Cray tinha oito "registradores vetoriais", que realizava 64 palavras de 64 bits cada. As instruções de vetores fora aplicadas entre os registros. O projeto Cray utilizava paralelismo para implementar instruções vetoriais ao invés ULAs múltiplas. Além disso, a concepção tinha condutas completamente separadas para diferentes instruções, por exemplo, adição/subtração foram implementadas em hardware e eram diferentes do que a multiplicação. Isto permitiu um lote de instruções próprias do vetor a ser pipeline, esta técnica foi chamada de encadeamento de vetor. O Cray-1 teve um desempenho de 80 MFlops, mas com no máximo três cadeias ao executá-lo poderia atingir o pico em 240 MFlops, um número que passou a ser respeitável a partir de 2002.

A Control Data Corporation tentou entrar no mercado dos supercomputadores com a sua máquina ETA-10, mas venderam muito pouco, e tomaram isso como uma oportunidade de sair do campo de supercomputadores. Em meados da década de 1980 japoneses (Fujitsu, Hitachi e Nippon Electric Corporation (NEC)) introduziram máquinas de vetores baseados no Cray-1, sendo um pouco mais rápidas e menores. No entanto, o Cray continuou a ser o líder em desempenho, antevindo uma série de maquinas que passou a existir depois dele, Cray-2, Cray X-MP e Cray Y-MP. Desde então o mercado dos supercomputadores tem focado em processamento paralelo ao invés de melhores implementações de processadores vetoriais. Reconhecendo os benefícios do processamento vetorial a IBM desenvolveu arquitetura virtual de vetor para uso em supercomputadores, acoplando vários processadores escalares para agir como um processador vetorial.

SIMD

Técnicas de processamento vetorial já foram adicionadas a quase todos os projetos modernos de CPU, apesar de serem normalmente referenciados como SIMD. Nestas implementações o vetor de unidade corre ao lado da CPU escalar principal, e é alimentado a partir de dados de programas de reconhecimento de instruções de vetor.

Descrição

editar

Em termos gerais, os processadores são capazes de manipular um ou dois pedaços de dados de cada vez. Por exemplo, a maioria dos processadores têm uma instrução que basicamente diz "adicionar A para B e colocar o resultado em C". Os dados para A, B e C podem ser pelo menos, codificados diretamente na instrução. No entanto, em implementações eficientes raramente são tão simples assim. Os dados são raramente enviados em forma bruta, e em vez disso é "apontado" ao passar em um endereço para um local de memória que contém os dados. Decodificar este endereço e obter os dados fora da memória leva algum tempo. Como as velocidades de CPU têm aumentado, esta latência de memória historicamente tem se tornado um grande impedimento para o desempenho.

A fim de reduzir a quantidade de tempo consumido por estas etapas, a maioria dos processadores modernos utilizam uma técnica conhecida como pipeline de instrução em que as instruções passam através de várias sub-unidades. A primeira sub-unidade lê o endereço e o decodifica, o próximo "busca" os valores para esses endereços, e a próxima faz o cálculo da instrução. Após buscar a primeira instrução, é mandado para o próximo estágio do pipeline, na forma de uma linha de montagem, de modo que o decodificador de endereços está constantemente em uso. Qualquer instrução particular leva a mesma quantidade de tempo para completar, um tempo conhecido como a latência, mas a CPU pode processar um lote inteiro de operações muito mais rapidamente e de forma mais eficiente do que fazendo um de cada vez.

Os processadores vetoriais levam este conceito um passo adiante. Em vez de constantemente decodificar instruções e, em seguida, obter os dados necessários para concluir-los, o processador lê uma única instrução de memória, e é simplesmente implícita na própria definição da instrução que vai operar a instrução novamente em outro item de dados, em um endereço de um incremento maior do que o último. Isso permite uma economia significativa no tempo de decodificação.

Existem vários contextos inerentes a esta abordagem. Por um lado, são necessárias apenas duas traduções de endereço. Dependendo da arquitetura, isso pode representar uma economia significativa por si só. Outra economia é buscar e decodificar a própria instrução, o que tem que ser feito apenas uma vez, em vez de dez. O próprio código também é menor, o que pode conduzir a uma utilização mais eficiente da memória.

Mas mais do que isso, um processador de vetor pode ter várias unidades funcionais adicionando esses números em paralelo. Na verificação de dependências entre esses números não é necessário que uma instrução de vetor especifique várias operações independentes. Isso simplifica a lógica de controle necessário, e pode melhorar o desempenho.

Como mencionado anteriormente, as implementações Cray levaram isso um passo adiante, permitindo que diversos tipos de operações fosem realizadas ao mesmo tempo. Considere o código que adiciona dois números e depois multiplica por um terceiro; no Cray, isso é obtido de uma só vez, e ambos adicionados e multiplicados em uma única operação.

As operações matemáticas são rápidas em geral, o fator limitante é o tempo necessário para buscar os dados da memória.

Nem todos os problemas podem ser resolvidos com esse tipo de solução. Adicionando-se estes tipos de instruções necessariamente aumenta-se a complexidade do CPU de núcleo. Essa complexidade normalmente resulta em outras instruções mais lentas. As instruções mais complexas, também aumentam a complexidade dos descodificadores, que podem abrandar a descodificação das instruções mais comuns.

Na verdade, os processadores vetoriais funcionam melhor apenas quando há grandes quantidades de dados a serem trabalhados. Por esta razão, estes tipos de CPUs foram encontrados principalmente em supercomputadores, como os supercomputadores próprios eram, em geral, encontrados em locais como centros de previsão do tempo e laboratórios de física, onde grandes quantidades de dados são "processados".

Programação em arquiteturas de computadores heterogêneos

editar

Várias máquinas foram projetadas para incluir os processadores tradicionais e os processadores vetoriais, como a Fujitsu AP1000 e AP3000. A programação em tais máquina heterogêneas pode ser difícil, pois o desenvolvimento de programas que fazem melhor uso de características de diferentes processadores aumenta o fardo do programador. Ele aumenta a complexidade do código e diminui a portabilidade, exigindo código específico de hardware para ser intercalado durante todo o código da aplicação.[2] Equilibrar a carga de trabalho de aplicativos em processadores pode ser difícil, especialmente tendo em conta que ele normalmente têm diferentes características de desempenho. Existem diferentes modelos conceituais para lidar com o problema, por exemplo, usando uma linguagem de coordenação e blocos de construção do programa. Cada bloco pode ter uma implementação nativa diferente para cada tipo de processador. Os usuários simplesmente programam usando essas abstrações e um compilador inteligente escolhe a melhor aplicação com base no contexto.[3]

Referências

  1. Malinovsky, B.N. (1995). The history of computer technology in their faces (in Russian). (see also here http://www.sigcis.org/files/SIGCISMC2010_001.pdf and english version here). Kiew: Firm "KIT". ISBN 5-7707-6131-8 
  2. Kunzman, D.M.; L.V. (1 de maio de 2011). «Programming Heterogeneous Systems». 2011 IEEE International Symposium on Parallel and Distributed Processing Workshops and Phd Forum (IPDPSW): 2061-2064. doi:10.1109/IPDPS.2011.377 
  3. John Darlinton, Moustafa Ghanem, Yike Guo, Hing Wing To (1996), «Guided Resource Organisation in Heterogeneous Parallel Computing», Journal of High Performance Computing, 4 (1): 13–23 
  • Este artigo foi inicialmente traduzido, total ou parcialmente, do artigo da Wikipédia em inglês cujo título é «Vector processor».