• Drano Rauteon

GPU: Como Funciona? - Parte 5

Aqui começaremos a descrever o funcionamento de uma GPU com Shaders Unificados.

Vamos começar pela arquitetura Tesla, da nVidia.

As unidades Shader agora são núcleos capazes de trabalhar tanto com o estágio de Geometria quanto com estágio de Rasterização do Pipeline de Gráficos, ou seja, agora operam com as instruções Vertex Shader e com as instruções Pixel Shader. Para melhorar a situação, os Shaders Unificados permitiram a criação do conjunto de instruções Geometry Shader, que torna a GPU apta a trabalhar na criação de primitivas gráficas, ou seja, auxiliando e aliviando o trabalho da CPU no estágio de Aplicação do Pipeline de Gráficos.


CURIOSIDADE: O DirectX 10 que trouxe o Shader Model 4.0, que incluía o conjunto de instruções do sombreador de geometria e já era programado para trabalhar em GPU's com Shader Unificado.


As unidades Shader agora são núcleos de propósito geral, isto é, núcleos de processamento feitos para operarem com processamento de software e com gráficos.

Uma das diferenças crucias entre os sistema anterior e o sistema de Shaders unificados é que agora eles não trabalham mais com um sistema SIMD, mas sim um sistema SIMT. O que seriam estes termos?


→ SISD (Single Instruction, Single Data): Não expressam nenhum paralelismo, classe que representa as arquiteturas que trabalham com um único fluxo de instruções e um único fluxo de dados. Remete ao Modelo de von Neumann com execução sequencial;


→ SIMD (Single Instruction, Multiple Data): Máquinas que executam exatamente o mesmo fluxo de instruções (mesmo programa) em cada uma das suas unidades de execução paralela, considerando fluxos de dados distintos. Um bom exemplo são as unidades de sombreamento de Pixel da arquitetura nVidia Kelvin, Rankine e Curie, que operam executando uma instrução Pixel Shader e com ela processam vários fragmentos que formam a imagem. Outro exemplo é a arquitetura TeraScale da AMD, que será muito bem detalhada no Capítulo 6 desta série;


→ MIMD (Multiple Instruction, Multiple Data): Máquinas paralelas que executam fluxos independentes e separados de instruções em suas unidades de processamento. Pode-se ter programas diferentes e independentes que processam entradas diferentes, múltiplos fluxos de dados.

Outra classificação essencial é aquela que divide as máquinas segundo o compartilhamento de memória. Esta classificação é importante, pois é diretamente responsável pelo modelo de programação a ser empregado no desenvolvimento das aplicações:


→ Multiprocessadores: máquinas com memória compartilhada (UMA e NUMA, com velocidades de acesso uniforme à memória e não uniforme à memória, respectivamente), possibilitam o modelo de programação multi thread, que é o que ocorre nas GPU's com Shaders unificados;


→ Multicomputadores: máquinas onde cada elemento de processamento possui a sua própria memória (NORMA), exigem o modelo de programação através da troca de mensagens entre seus componentes;


Ainda existem outras classificações:


→ SPMD (Single Program, Multiple Data): Este modelo é mais geral que o modelo SIMD (Single Instruction, Multiple Data) e que o modelo data-parallel, pois o SPMD usa aplicações com paralelismo de dados e paralelismo de threads;

→ SIMT (Single Instruction, Multiple Threads): Modelo utilizado para gerenciar a execução de várias tarefas através de uma instrução. Termo utilizado pela Nvidia para os chip's gráficos que trabalham com a tecnologia CUDA;


→ MSIMD (Multiple SIMD): Máquinas que possuem um memória global de tamanho ilimitado, e “N” processadores SIMD independentes. Autores definiram (Bridges, 1990) e utilizam (Jurkiewicz and Danilewski, 2011) esta denominação.

Arquitetura Tesla.


Vamos começar a estudar a arquitetura Tesla (2006 ~ 2013)


Veja o digaram de um bloco TPC da arquitetura Tesla abaixo:

Diagrama 1 - Bloco TPC


Os CUDA Cores (Shaders Unificados) são organizados em blocos de hardware formados da seguinte forma:


1. TPC (Texture Processing Cluster): Na arquitetura Tesla são os clusters de hardware com SM's. Na arquitetura Pascal, as TPC's voltaram. Elas ficam dentro das GPC's e possuem o circuito Polymorfh Engine e uma unidade SM;


2. Dentro de um bloco TPC, antes dos SM's, há um Geometry Controller, que de forma resumida e grosseira e responsável por organizar os dados referentes a etapa de Geometria do Pipeline gráfico, além de organizar os dados que vão para o bloco SMC.

Apesar de trabalhar com vértices (etapa de Geometria), faz apenas a montagem, o direcionamento dos dados referentes as coordenadas "Z" (de profundidade) para o Z-Buffer e dá início a rasterização, porém as primitivas gráficas "brutas" (ou outro tipo de dado, afinal é uma GPGPU) já separadas em tarefas serão processadas pelos shaders unificados que vem na sequência. Para entender melhor estes termos e o funcionamento dos circuitos deste bloco de hardware, volte ao Capítulo 4 desta série de artigos. Em partes, pode equivaler a Unidade Setup Engine presente na arquitetura TeraScale ou ao bloco Geometry / Rasterizer da arquitetura GCN, ambas da AMD;


3. SMC: Os Stream Multiprocessor Controller são nada mais que blocos que gerenciam os dados e instruções que entram no TPC e precisam ser distribuídos entre os dois blocos SM;


4. SM: São os principais itens dentro de um TPC. A arquitetura Fermi trás dois SM's em cada TPC. Dentro de um SM é que ficam os núcleos de processamento;


5. Instruction Cache (I Cache): Na entrada de cada SM há uma memória cache para armazenar instruções (instruções diversas, como por exemplo as instruções Vertex Shader);


6. MT IU: Cada bloco SM possui um limite de tarefas (Threads), e no caso da arquitetura Tesla são 32 Threads. O Multi-Thread Issue Unit (Unidade de Emissão Multi-Tarefas), também conhecido como Warp Scheduler (Agendador de Urdidura) é responsável por agendar as tarefas para a(s) Unidade(s) de Despacho, que enviam os dados para o Register File;


6. Constants Cache: A memória “cache de constantes” é a Unidade de Despacho citada no tópico anterior;


7. Register File (RF): Para que você entenda melhor, um registrador armazena temporariamente e movimenta dados de acordo com a necessidade de utilização deles pelas instruções de processamento. Antes dos dados seguirem das Unidades de Despacho para os CUDA Cores e SFU's, eles atravessam um circuito chamado de Register File (arquivo de registro), que normalmente é de 32 bits. Veja como as arquitetura nVidia evoluíram com os exemplos abaixo:

-> Arquitetura Tesla: 1.024 entradas de 32 bits;

-> Arquitetura Fermi: 32.768 entradas de 32 bits

-> Arquitetura Kepler: 65.536 entradas de 32 bits cada.


8. Stream Processors (SP): Este termo é utilizado para definir os Shaders Unificados de chip's da AMD, porém ele também pode ser usado para chamar os CUDA Cores da nVidia. Cada Stream Processor consegue executar uma Thread (Tarefa) por ciclo de clock para cada instrução dada. Dentro de um SM da arquitetura Tesla há 8 Stream Processors;


9. SFU's (Special Function Units): Executam as instruções transcendentais, como por exemplo o seno, cosseno e raiz quadrada. Cada SFU executa uma multiplicação de ponto flutuante por ciclo de clock e até quatro funções especiais por ciclo de clock. A pipeline (canalização de dados) de um SFU é desacoplada da Unidade de Despacho, permitindo que a Unidade de Despacho seja direcionada para outras unidades de execução enquanto um SFU estiver ocupado. Na arquitetura Tesla são duas unidades SFU para cada Stream Multiprocessor (SM);


10. Os dois SM's compartilham um mesmo bloco de memória cache;


11. TMU: As unidades de processamento de textura estão fora dos SM's, mas dentro do TPC. As TMU's são acopladas aos dois Stream Multiprocessors (SM) e possuem sua memória cache para texturas. Na arquitetura Tesla, há 4 unidades TMU dentro de cada TPC;


OBSERVAÇÃO: Os núcleos CUDA, SFU's, LD/ST Unit's e o Register File são conectados por uma espécie de barramento de intercomunicação bidirecional, que pode movimentar dados em ambas as direções entre os circuitos citados dentro de um SM. Você verá mais abaixo sobre a arquitetura Fermi e também no Capítulo 7 (sobre a microarquitetura Kepler e Maxwell), que nelas esta intercomunicação bidirecional abrange também as TMU's.


-> As unidades ROP estão desacopladas dos TPC's. Veja o diagrama abaixo:


Diagrama 2 - Os clusters TPC e as unidades ROP


12. São 24 unidades ROP operando para os oito blocos TPC do chip G80, da arquitetura Tesla;


13. São 6 controladores de memória RAM (os blocos "MC" em vermelho);


14. O bloco "rasterizer" é o responsável por montar o quadro na saída de rasterização e passa-lo aos controladores de interface de vídeo;


15. O bloco "Command Processor" é o que rege o funcionamento dos TPC's, pois obviamente um conjunto de clusters de processadores precisa de um sistema de gerenciamento.


CURIOSIDADE: A Arquitetura Tesla possui duas gerações. São elas:

-> Tesla: C77, C78, C79, C7A, C7A-ION, G80, G84, G86, G92, G92B, G94, G94B, G96, G96C, G98 e ION;

-> Tesla 2.0: C87, C89, GT200, GT200B, GT215, GT216 e GT218.


CODIFICAÇÃO e DECODIFIOCAÇÃO de VÍDEO


A arquitetura Tesla ainda não integra um codificador de vídeo, portanto esta parte acaba sendo feita pela CPU do computador.

A arquitetura Tesla integra a segunda geração do PureVideo HD, um bloco de hardware dedicado para a decodificação de vídeo, isto é, reprodução de conteúdo multimídia (Vídeos, Fotos e Áudio).

A segunda geração PureVideo HD adicionou um processador de fluxo de bits dedicado (BSP - Bit Signal Processor) e um processador de vídeo aprimorado, para otimizar o pipeline de decodificação do formato H.264. Para o formato VC-1 também houve melhorias, agora com a pipeline de decodificação VC-1 suportando transformada discreta inversa de cosseno (iDCT) e estágios de compensação de movimento. O pipeline de front-end (fluxo de bits) ainda é decodificado pela CPU. A segunda geração do PureVideo HD permitiu que os PC's convencionais reproduzissem filmes gravados em HD-DVD e Blu-ray, com a maior parte da decodificação de vídeo feita pela GPU.


A terceira geração do PureVideo HD trouxe melhoria pro sistema de decodificação para o formato VC-1 com o chip G98 (vendida como GeForce 8400GS), bem como pequenas melhorias adicionais para o bloco de decodificação MPEG-2. O bloco de decodificação do formato H.264 não foi alterada. Em essência, o VP3 oferece decodificação de hardware completa para todos os 3 codec's de vídeo do formato de disco Blu-Ray: MPEG-2, VC-1 e H.264.

O bloco de hardware do PureVideo HD de terceira geração (utilizado no chip gráfico G98 e nos chipset's com processador gráfico integrado MCP77, MCP78, MCP79MX, MCP7A) não pode decodificar H.264 para as seguintes resoluções horizontais: 769–784, 849–864, 929–944, 1009–1024, 1793–1808, 1873–1888, 1953–1968 e 2033–2048 pixels.


A quarta geração do PureVideo HD (VP4) adicionou hardware para suportar o MPEG-4 Advanced Simple Profile (o formato de compressão implementado pelo DivX e Xvid original), decodificação de bitstream com os chip's GT215, GT216 e GT218 (vendidas como GeForce GT 240, GeForce GT 220 e GeForce 210 / G210, respectivamente). O decodificador H.264 não sofre mais as restrições de tamanho de quadro do VP3 e adiciona aceleração de hardware para MVC (Multiview Video Coding), uma extensão H.264 usada em discos Blu-Ray 3D. A aceleração MVC depende do sistema operacional: é totalmente compatível com o Microsoft Windows por meio das API's DXVA (DirectX Video Acceleration) e Nvidia CUDA, mas não é compatível com a API VDPAU (Video Decode and Presentation API for Unix - API de Decodificação e Apresentação de Vídeo para Unix) da Nvidia.


Arquitetura Fermi (2010 ~ 2016)


Veja abaixo um bloco SM da arquitetura Fermi:

Diagrama 3 - Um bloco SM da arquitetura Fermi


A arquitetura Fermi abandona o conceito de TPC e passa a utilizar GPC's nos chip's.

Diagrama 4 - Um cluster GPC da Fermi


1. GPC (Graphics Processing Cluster): São clusters de SM's, isto é, possuem várias unidades SM em seu interior controladas por um circuito chamado de Raster Engine. Alguns chips gráficos possuem, por exemplo, 2 GPC's com 2 SM e mais 1 GPC com 1 SM.

Como já foi estudado, este “agrupamento” de SM's veio a partir da arquitetura Fermi. Antes da arquitetura Fermi, o agrupamento de SM's era feito em blocos de hardware chamados de TPC (Texture Processing Cluster) que incluíam unidades de processamento de textura (TMU) com memória cache, um SMC (Stream Multiprocessor Controller) e um Geometry Controller.

Somente a partir da arquitetura Fermi, as TMU's (Texture Mapping Unit) foram colocadas dentro dos SM's;


2. Raster Engine: Este bloco de hardware substituiu o Stream Multiprocessor Controller (SMC) e o Geometry Controller da arquitetura Tesla. Ele possui a mesma função dos dois blocos da arquitetura Tesla, isto é, o gerenciamento dos dados que são trocados com cada bloco SM (Stream Multiprocessor). Cada GPC possui uma unidade Raster Engine.

Apesar de trabalhar com vértices (etapa de Geometria), a Raster Engine faz apenas a montagem, o direcionamento dos dados referentes as coordenadas "Z" (de profundidade) para o Z-Buffer e dá início a rasterização, porém as primitivas gráficas "brutas" (ou outro tipo de dado, afinal é uma GPGPU) já separadas em tarefas serão processadas pelos shaders unificados que vem na sequência. Para entender melhor estes termos e o funcionamento dos circuitos deste bloco de hardware, volte ao Capítulo 4 desta série de artigos. Em partes, pode equivaler a Unidade Setup Engine presente na arquitetura TeraScale ou ao bloco Geometry / Rasterizer da arquitetura GCN, ambas da AMD;


3. Instruction Cache (I Cache): Na entrada de cada SM há uma memória cache para armazenar instruções (instruções diversas, como por exemplo as instruções Vertex Shader);


4. MT IU: Cada bloco SM possui um limite de tarefas (Threads), e no caso da arquitetura Fermi são 64 Threads. O Multi-Thread Issue Unit (Unidade de Emissão Multi-Tarefas), também conhecido como Warp Scheduler (Agendador de Urdidura) é responsável por agendar as tarefas para a(s) Unidade(s) de Despacho, que enviam os dados para o Register File. Como você pode ver no diagrama do Stream Multiprocessor da Fermi, há duas unidades Warp Scheduler, cada uma possuindo um limite de gerenciamento de 32 tarefas;


6. Constants Cache: A memória “cache de constantes” é a Unidade de Despacho citada no tópico anterior. Cada bloco SM da arquitetura Fermi tem duas Unidades de Despacho;


7. Register File (RF): Para que você entenda melhor, um registrador armazena temporariamente e movimenta dados de acordo com a necessidade de utilização deles pelas instruções de processamento. Antes dos dados seguirem das Unidades de Despacho para os CUDA Cores e SFU's, eles atravessam um circuito chamado de Register File (arquivo de registro), que normalmente é de 32 bits. Veja como as arquitetura nVidia evoluíram com os exemplos abaixo:

-> Arquitetura Tesla: 1.024 entradas de 32 bits;

-> Arquitetura Fermi: 32.768 entradas de 32 bits

-> Arquitetura Kepler: 65.536 entradas de 32 bits cada.


8. Stream Processors (SP): Este termo é utilizado para definir os Shaders Unificados de chip's da AMD, porém ele também pode ser usado para chamar os CUDA Cores da nVidia. Cada Stream Processor consegue executar uma Thread (Tarefa) por ciclo de clock para cada instrução dada. Dentro de um SM da arquitetura Fermi há 32 CUDA Cores;


9. LD/ST Units (Unidades Load/Store): Foram adicionadas aos SM's a partir da arquitetura Fermi. São unidades de carga e armazenamento. Estas unidades calculam os endereços de origem e de destino dos dados de 16 Threads por ciclo de clock. Resumidamente sua função é carregar e armazenar os dados de / para armazenar em cache ou memória RAM.


OBSERVAÇÃO: Os núcleos CUDA, SFU's, LD/ST Unit's, TMU's e o Register File são conectados por uma espécie de barramento de intercomunicação bidirecional, que pode movimentar dados em ambas as direções entre os circuitos citados dentro de um SM.


Aqui entram mais alguns detalhes. Sabendo que cada CUDA Core consegue executar uma tarefa (thread), como que a arquitetura Fermi tem capacidade de 64 thread em dois Warp Scheduler e apenas 32 Stream processors?

Isso ocorre pois os CUDA Cores trabalham com o dobro do clock do restante do SM. Além disso, os 32 CUDA Cores são divididos em dois grupos de 16, sendo cada grupo responsável por trabalhar em conjunto com um Warp Scheduler. Se cada Unidade Warp trabalha com 32 Threads e alimenta um grupo de 16 Stream Processor operando com o dobro de clock, isso significa não há gargalo no sistema.


10. SFU's (Special Function Units): Executam as instruções transcendentais, como por exemplo o seno, cosseno, raiz quadrada inversa, exp e rcp. Cada SFU executa uma multiplicação de ponto flutuante por ciclo de clock e até quatro funções especiais por ciclo de clock. A pipeline (canalização de dados) de um SFU é desacoplada da Unidade de Despacho, permitindo que a Unidade de Despacho seja direcionada para outras unidades de execução enquanto um SFU estiver ocupado. Na arquitetura Fermi são quatro unidades SFU para cada Stream Multiprocessor (SM);


11. Cada bloco SM possui 64 kB de memória cache;


12. TMU: As unidades de processamento de textura estão dentro dos SM's na arquitetura Fermi. As TMU's possuem sua memória cache para texturas. Na arquitetura Fermi, há 4 unidades TMU dentro de cada SM;


13. Na arquitetura Fermi temos a introduçaõ do bloco de harwdare chamado Polymorph Engine. É um circuito criado para lidar com a grande quantidade de trabalho gerado pelas novas funções introduzidas na API DirectX 11, entre estas funções está o Tesselation (“tesselação”, em português). O tesselation subdivide um polígono da imagem em formas geométricas menores para que seja mostrado mais informações, detalhes do objeto, e tudo isso através de um deslocamento de vértices através de uma técnica chamada de “mapeamento de deslocamento”.

No Polymorph Engine 2.0 há 5 circuitos, apresentados em ordem abaixo:

-> Vertex Fetch (Busca de vértice);

-> Tesselator (Tesselador);

-> ViewPort Transform (Transformada de exibição);

-> Atribute Setup (Configuração de atributo);

-> Stream Output (Saída de Fluxo).


Já a versão 3.0 possui dois circuitos Vertex Fetch e dois Atribute Setup. O bloco Polymorph Engine está atrelado a etapa de Geometria do Pipeline de Gráficos, portanto vemos a palavra "ViewPort" e já lembramos dos sistemas de coordenadas descritos em artigos anteriores.

Para conhecer mais sobre o Tesselation, veja este artigo "printado" dos antigos sites da nVidia:

Print 1 - Tesselation explicado pela nVidia


CURIOSIDADE: O Tesselation já havia sido implementado no DirectX 8.1, lá de 2001, porém foi abandonado pois não foi estipulado um bloco de hardware dedicado para o processamento desse algoritmo na GPU. Apenas alguns chip's da ATi suportaram esta tecnologia (como por exemplo a Radeon 8500).

Diagrama 5 - Diagrama de blocos do chip GF100 com arquitetura Fermi


14. São 48 unidades ROP dividias em 6 blocos e operando para os quatro clusters GPC do chip GF100 da arquitetura Fermi;


15. Há uma memória cache L2 para todos os clusters GPC e ela é interligada nas unidades ROP, possuindo também conexão direta com os controladores de memória RAM e com o Giga-Thread Engine;


16. São 6 blocos Memory Controller, totalizando 12 controladores de memória RAM com barramento de 32 bits cada, permitindo que haja um barramento de até 384 bits ligando o chip GF100 aos chip's GDDR;


17. Na arquitetura Fermi, o bloco "Command Processor" da Tesla foi substituído pelo bloco de hardware "Giga Thread Engine", que está ligado na interface PCI Express, nos controladores de memória RAM em em todos os clusters e memória cache L2;


18. No diagrama mostrado não há o "display controller", porém ele também está presente nas Fermi, afinal ele recebe o quadro da Saída de Rasterização (ROP) ou o quadro vindo do decodificador de vídeo e empacota os dados no protocolo da interface de vídeo, seja ela DVI, VGA ou S-Vídeo (conversor digital/analógico RAMDAC), HDMI ou DisplayPort.


CURIOSIDADE: A arquitetura Fermi é dividida em duas gerações. São elas:

-> Fermi: GF100, GF104, GF106 e GF108;

-> Fermi 2.0: GF110, GF114, GF116, GF117 e GF119.


CODIFICAÇÃO e DECODIFIOCAÇÃO de VÍDEO


A arquitetura Fermi ainda não integra um codificador de vídeo, portanto esta parte acaba sendo feita pela CPU do computador.


A arquitetura Fermi integra a quinta geração do PureVideo HD, um bloco de hardware dedicado para a decodificação de vídeo, isto é, reprodução de conteúdo multimídia (Vídeos, Fotos e Áudio). O PureVideo HD 5 melhorou o sistema de decodificação H.264 e permitiu resoluções em 4K (2160p, ou seja, 4x a resolução Full HD).

Para encerrarmos o artigo, um segundo diagrama do SM da arquitetura Fermi mostrando o que há dentro de um CUDA Core.

Diagrama 6 - O que há dentro de um CUDA Core


Como você pode ver, um núcleo CUDA (na arquitetura Fermi), possui uma unidade de Ponto Flutuante (FP Unit) e uma de Inteiros (INT Unit). A unidade Warp Scheduler direciona uma Thread ao núcleo, que a recebe pela Porta de Despacho para Coletor de Operandos, onde será distribuída entre as duas unidades. Após ser processada, a tarefa é enviada para a fila de resultados (Result Queue). Lembrando que, na Fermi, o CUDA Core trabalha com 2x o clock do Warp Scheduler.

É válido lembrar que, um núcleo CUDA opera com pontos flutuantes de 32 bits (FP32) ou de 16 bits (FP16 - Ponto Flutuante de meia precisão), e algumas arquiteturas, como por exemplo a Kepler, possuem outros blocos de hardware denominados "DP Unit" para processar pontos flutuantes de dupla precisão (FP64). Um hardware sem Unidades de Dupla Precisão dedicadas só consegue processar FP64 de forma virtual, utilizando dois núcleos FP32.

Quanto a INT Unit, a Tesla consegue fazer a multiplicação de números inteiros com uma ALU (Unidade Lógica Aritmética) de 24 bits, enquanto a Fermi já consegue uma INT32. O processamento de FP32 e INT32 de forma paralela e simultânea só foi possível a partir da Arquitetura Turing, em 2018, quando o CUDA Core foi desmembrado, resultando em unidades de ponto flutuante de precisão simples e unidades de números inteiros separadas.


Mas o que seria uma tarefa dentro de um chip gráfico?

Imagine que você está em um escritório, com 6 funcionários, cada um cuidando de seu departamento. Vocês devem preencher um documento, e cada funcionário preenche a parte do documento que lhe diz respeito, isto é, cada funcionário com uma tarefa diferente para executar. Quem passa o documento de departamento em departamento é uma 'espécie' de Office Boy. O Office Boy agenda, distribui e organiza as tarefas para que os documentos sejam completados. Esse é um exemplo genérico, pra leigo entender.

Trocando em miúdos, a placa de vídeo é o escritório, os funcionários são os núcleos de processamento e o office boy é toda a parte de Management (cache, Warp Scheduler, Register File e afins) para que ao final os documentos, que neste caso são dados, sejam completados. Esses dados podem ser de um software, de um game, de um vídeo ou de uma simples foto, já que estamos falando de um sistema de Propósito Geral (GPGPU).

--------------------------------------------------------------------------------

Se encontrou alguma inconsistência, quer mandar alguma sugestão, elgio ou algum complemento a este texto, não deixe de entrar em contato conosco pelo e-mail hardwarecentrallr@gmail.com

Texto: Leonardo Ritter.

Imagens e diagramas: TechPower Up e Leonardo Ritter.

Fontes: TechPower Up, Wikipedia (somente artigos com fontes verificadas!).

53 visualizações

© 2020 Hardware Central Tecnologia Entretenimento e Comunicação do Brasil Ltda. Todos os direitos reservados.

Wix Editor / Revisão da web page: 3.1/2020 (16/07/20)