GPUs modernas: Quão “inteligentes” são?

11

Existem muitos recursos em programação 3D (OpenGL ou DirectX) e os pipelines gráficos correspondentes disponíveis, mas estou me perguntando em que nível eles são implementados em uma GPU moderna.

Até agora, pude descobrir que houve uma mudança do circuito especializado que implementa os vários estágios do pipeline gráfico para uma abordagem mais geral. Essa transformação foi parcialmente refletida nas APIs 3D na forma de sombreadores programáveis. A maioria dos transistores parece dedicada a unidades SIMD massivamente paralelas que executam as instruções reais do shader.

Mas e o resto do pipeline de gráficos? Isso ainda está implementado em hardware?

É uma GPU moderna (pense na Nvidia Fermi) basicamente um conjunto de matrizes SIMD "estúpidas" que são alimentadas com instruções e dados da CPU e vários caches, e toda a lógica real que mapeia o pipeline gráfico para essas instruções acontece no driver gráfico ?

Ou existem algumas unidades de controle em algum lugar da GPU que convertem as instruções de alto nível e os fluxos de dados de entrada (programas shader compilados, dados e atributos de vértices e texturas) em instruções SIMD reais e cuidam da sincronização, alocação de memória etc.?

Suspeito que a realidade esteja entre esses dois extremos, e a resposta seria bastante longa e baseada em muita especulação (deve haver uma razão para que certos fornecedores de GPU se recusem a publicar qualquer documentação em seus produtos, muito menos em drivers). código-fonte ...), mas qualquer dica na direção certa e recursos úteis serão muito apreciados.

Até agora, encontrei uma série de postagens de blog que foram imensamente úteis para entender mais sobre as GPUs modernas, mas estou perdendo algum tipo de visão geral de nível mais alto sobre a arquitetura geral - eu posso entender a maioria dos conceitos mencionados, mas não entendo como eles se encaixam.

lxgr
fonte

Respostas:

8

Até agora, pude descobrir que houve uma mudança do circuito especializado que implementa os vários estágios do pipeline gráfico para uma abordagem mais geral. Essa transformação foi parcialmente refletida nas APIs 3D na forma de sombreadores programáveis. A maioria dos transistores parece dedicada a unidades SIMD massivamente paralelas que executam as instruções reais do shader.

Corrigir. Basicamente, devido ao tamanho de recurso relativamente grande nas GPUs antigas, a única maneira de implementar com eficiência itens como iluminação básica, antialiasing, mapeamento de textura, geometria etc. era usar um pipeline de "função fixa". Eles sacrificaram a flexibilidade por uma questão de desempenho, porque não tinham densidade de chip suficiente para poder implementá-la usando uma arquitetura SIMD massivamente paralela mais genérica, como as GPUs atuais.

É uma GPU moderna (pense na Nvidia Fermi) basicamente um conjunto de matrizes SIMD "estúpidas" que são alimentadas com instruções e dados da CPU e vários caches, e toda a lógica real que mapeia o pipeline gráfico para essas instruções acontece no driver gráfico ?

Certas coisas ainda são feitas no hardware; outros não são. Por exemplo, os ROPs ainda são usados ​​no estágio final para inserir dados de pixel no chipset VGA. Note que estou usando "chipset VGA" aqui como um termo genérico para se referir ao mecanismo que transmite um sinal de vídeo para o seu monitor, independentemente de ser realmente "VGA" em qualquer aspecto.

É verdade, em geral, que as arquiteturas atuais de GPU, como a Nvidia Fermi e a AMD Southern Islands, são, na maioria das vezes, CPUs massivamente paralelas, onde eles têm um conjunto de instruções personalizado, e cada "núcleo" individual é extremamente fraco, mas há um todo monte de núcleos (às vezes vários milhares). Mas ainda há hardware específico para gráficos:

  • A decodificação de vídeo de hardware geralmente é feita, em grande parte, usando chips de função fixa. Isso é particularmente verdadeiro quando o DRM (Gerenciamento de restrições digitais) está envolvido. Às vezes, a decodificação de vídeo com "hardware" significa realmente um conjunto de instruções guiadas por firmware, que são servidas apenas como tarefas antigas regulares para os núcleos do SIMD. Isso realmente depende.

  • Com exceção de poucas placas Nvidia específicas para computação (Tesla), quase todas as placas gráficas "genéricas SIMD" possuem uma gama completa de hardware dedicado à saída de vídeo. Saída de vídeo não é o mesmo que renderização; os elementos de saída de função fixa incluem codecs LVDS / TMDS / HDMI / DisplayPort, HDCP e até processamento de áudio (basicamente um pouco DSP), já que o HDMI suporta áudio.

  • A "memória gráfica" ainda é armazenada a bordo com as GPUs, para que elas não precisem atravessar o barramento PCIe falante e de latência relativamente alta para atingir a RAM do sistema, que é mais lenta e leva mais tempo para responder do que as mais caras, qualidade gráfica mais alta, memória gráfica mais rápida (por exemplo, GDDR5), disponível em capacidades menores, mas em velocidades mais altas que a memória do sistema. O processo de armazenar coisas na memória gráfica e recuperá-las de lá para a GPU ou para a CPU ainda é uma operação de função fixa. Algumas GPUs têm seu próprio tipo de "IOMMU", mas essa unidade de gerenciamento de memória é distinta (separada) da CPU. Isso não é verdade, no entanto, para as recentes GPUs Intel integradas em seus processadores (Sandy e Ivy Bridge), onde a arquitetura de memória é quase inteiramente "coerente" memória do sistema) e as leituras da memória gráfica são tão baratas para a CPU quanto para a GPU.

Ou existem algumas unidades de controle em algum lugar da GPU que convertem as instruções de alto nível e os fluxos de dados de entrada (programas shader compilados, dados e atributos de vértices e texturas) em instruções SIMD reais e cuidam da sincronização, alocação de memória etc.?

O idioma "nativo" dos SIMDs quase sempre é gerado pelo driver do software, e não pelo firmware da GPU. Isto é especialmente verdade para os recursos de nível DirectX 9 / OpenGL 2.x. Os shaders escritos em linguagens de alto nível, como o HLSL, GLSL ou o OpenGL ARB shader assembler, são eventualmente traduzidos, pelo driver, em instruções da GPU, pressionando determinados registradores e executando os hoops PCIe necessários para enviar buffers em lote de computação e / ou renderização comandos.

Algumas coisas, como mosaico de hardware (DirectX 11 / OpenGL 4.0), são novamente introduzidas no hardware de maneira fixa, semelhante à maneira como costumavam fazer quase tudo nos velhos tempos. Isso ocorre porque, novamente, as restrições de desempenho exigem que a maneira mais eficiente de fazer esses cálculos seja ter circuitos dedicados para isso, em vez de ter o firmware ou o driver "programa" os SIMDs para fazê-lo.

Suspeito que a realidade esteja entre esses dois extremos, e a resposta seria bastante longa e baseada em muita especulação (deve haver uma razão para que certos fornecedores de GPU se recusem a publicar qualquer documentação em seus produtos, muito menos em drivers). código-fonte ...), mas qualquer dica na direção certa e recursos úteis serão muito apreciados.

A AMD e a Intel têm uma documentação muito robusta e aberta sobre suas GPUs recentes, além de drivers gráficos de código aberto totalmente funcionais para Linux (consulte os projetos Mesa e Direct Rendering Manager). Se você observar um pouco do código desses drivers, você rirá, porque os gravadores de drivers gráficos realmente precisam implementar a geometria de coisas como desenhar várias formas ou padrões, no "software" (mas usando comandos de hardware para enviar as informações reais). trabalho manual para o hardware para processamento), porque nem o firmware da GPU nem as funções fixas estão presentes para processá-lo totalmente no hardware :) É meio engraçado o que eles precisam fazer para oferecer suporte ao OpenGL 1.x / 2.x em novos hardware.

A evolução meio que foi assim:

  • Há muito tempo (antes que a renderização em 3D em tempo real fosse considerada possível): o rastreamento de raios na CPU era normal para renderização em tempo não real. Para gráficos simples, como você vê nas versões anteriores do Windows, a CPU era rápida o suficiente para desenhar formas simples (retângulos, caracteres de uma fonte, padrões de sombreamento etc.) sem hardware de função fixo, mas não conseguia desenhar coisas muito complexas.
  • Há muito tempo (OpenGL 1.x): quase tudo implementado por hardware de estado sólido; funções fixas "eletricamente" eram a norma mesmo para operações básicas
  • Há um tempo atrás (OpenGL 2.x): Uma transição para tornar as GPUs mais programáveis ​​havia começado. "Fragmentos de sombreamento" (também conhecido como pixel shaders) em hardware de 5 anos pode quase realizar cálculos arbitrários como uma CPU, mas é limitado pela arquitetura, que ainda é muito voltada para gráficos. Portanto, o OpenCL / DirectCompute não está disponível neste hardware.
  • Recentemente (OpenGL 3.x): a transição para GPUs de uso geral é quase completa, mas é claro, otimizada para cargas de trabalho que envolvem grandes matrizes de dados (pense em álgebra linear) sendo enviadas em lotes, em vez de CPUs que podem operar com eficiência em seqüências longas de dados muito pequenos (1 + 1, 2 * 4, 5 * 6 em seqüência, etc.) A computação de uso geral está disponível via OpenCL, CUDA etc. etc., mas o hardware ainda não é um "coprocessador SIMD" completo porque (a) você ainda precisa martelar registros específicos de hardware para acessar a funcionalidade da GPU; (b) a leitura da GPU VRAM é muito lenta devido à sobrecarga do barramento PCIe (a leitura da GPU não é muito otimizada na arquitetura atual); (c) a arquitetura de memória e cache não é coerente com a CPU; ainda há muito hardware de função fixa herdado.
  • Presente (OpenGL 4.x): Livre-se de muitos hardwares de funções fixas herdadas. Melhorou a latência de leitura da GPU. As IOMMUs permitem um mapeamento assistido por hardware (traduzido) entre o VRAM e a memória do sistema. Também introduziu o mosaico de hardware, trazendo de volta elementos de função fixa.
  • Futuro ( HSA): A GPU é basicamente um co-processador. Está quase totalmente integrado à CPU com muito pouca impedância (para leituras / gravações) entre a GPU e a CPU, mesmo para GPUs dedicadas no barramento PCIe. Arquitetura de memória totalmente coerente - "mi memoria es su memoria" (minha memória é a sua memória). Os programas do espaço do usuário podem ler a partir do "VRAM", da mesma forma que lêem na memória do sistema, sem necessidade de calçar o driver, e o hardware cuida disso. Você tem a CPU para processamento "serial" (faça isso, faça isso e depois faça isso) para quantidades modestas de dados e a GPU para processamento "paralelo" (execute esta operação nesse enorme conjunto de dados e divida-o como você achar melhor). A placa na qual a GPU fica pode ainda ter ROPs, codec HDMI etc. etc., mas isso é necessário para a saída da tela,
allquixotic
fonte
Seu último ponto é ótimo e também se aplica a mais do que apenas o tipo de coisas OpenGL1.x / 2.x. Devido à incrível complexidade da lógica nas GPUs, é quase certo que haverá bugs em algum lugar. Normalmente, a maioria dos erros na lógica é eliminada antes que se torne um chip físico, mas pode haver alguns casos estranhos que ainda podem surgir. Quando isso acontece, os drivers terão que implementar o próprio recurso para ignorar a parte com erros do hardware. Geralmente, coisas como essa são as razões pelas quais você pode obter aprimoramentos de recursos / desempenho nas atualizações de drivers.
Ben Richards