Quando devo descarregar o trabalho para uma GPU em vez da CPU?

15

Estão sendo criados sistemas mais novos, como o OpenCL, para que possamos executar cada vez mais códigos em nossos processadores gráficos, o que faz sentido, porque devemos poder utilizar o máximo de energia possível em nossos sistemas.

No entanto, com todos esses novos sistemas, parece que as GPUs são melhores que as CPUs em todos os aspectos . Como as GPUs podem fazer cálculos paralelos, as GPUs com vários núcleos parecem realmente muito melhores que as CPUs com vários núcleos; você seria capaz de fazer muitos cálculos ao mesmo tempo e realmente melhorar a velocidade. Ainda existem certos casos em que o processamento serial ainda é melhor, mais rápido e / ou mais eficiente que o paralelo?

RétroX
fonte
6
Não é realmente uma pergunta sobre hardware. Deve ser reformulado para "quando programar a (s) CPU (s) melhor do que programar a (s) GPU (s)" e tal é uma boa pergunta p.se na IMO. Veja a tag GPGPU entre outros no SO. Mas a arquitetura "Que tecnologia usar" é melhor aqui do que ali.
Kate Gregory
1
@ Kate Esse ângulo parece estar muito bem abordado na questão vinculada de superusuário. Lendo, estou um pouco surpreso por não ter sido migrado para cá, para ser sincero. Há também isso no SO. Vou reabrir a pergunta (já que você está certo, os aspectos de programação estão no tópico aqui). Espero que vejamos uma resposta que não esteja apenas apontando para a cobertura (excelente) existente deste problema.
Adam Lear
1
Para @ Anna, acho que as respostas precisam ser muito mais sobre quando um programador deve usar a GPU, em vez de uma discussão puramente teórica sobre qual é a diferença entre uma GPU e uma CPU. Eu editei o título para refletir isso.
2
@RetroX Não podemos fechar perguntas como duplicadas se estiverem em sites diferentes.
Adam Lear

Respostas:

26

No entanto, com todos esses novos sistemas, parece que as GPUs são melhores do que as CPUs em todos os aspectos.

Este é um mal-entendido fundamental. Os núcleos atuais de GPU ainda são limitados em comparação com os atuais processadores de última geração. Eu acho que a arquitetura Fermi da NVIDIA é a GPU mais poderosa disponível atualmente. Ele possui apenas registros de 32 bits para aritmética inteira e menos capacidade para previsão de ramificação e execução especulativa do que um processador Intel atual. Os chips Intel i7 fornecem três níveis de armazenamento em cache, os núcleos Fermi têm apenas dois e cada cache no Fermi é menor que o cache correspondente no i7. A comunicação entre processos entre os núcleos da GPU é bastante limitada e seus cálculos precisam ser estruturados para acomodar essa limitação (os núcleos são agrupados em blocos e a comunicação entre os núcleos em um bloco é relativamente rápida, mas a comunicação entre os blocos é lenta).

Uma limitação significativa das GPUs atuais é que todos os núcleos precisam estar executando o mesmo código. Ao contrário dos núcleos em sua CPU, você não pode dizer um núcleo de GPU para executar seu cliente de email e outro núcleo para executar seu servidor da Web. Você atribui à GPU a função de inverter uma matriz e todos os núcleos executam essa função em diferentes bits de dados.

Os processadores na GPU vivem em um mundo isolado. Eles podem controlar a exibição, mas não têm acesso ao disco, à rede ou ao teclado.

O acesso ao sistema GPU tem custos indiretos substanciais. A GPU possui sua própria memória; portanto, seus cálculos serão limitados à quantidade de memória no cartão da GPU. A transferência de dados entre a memória da GPU e a memória principal é relativamente cara. Pragmaticamente, isso significa que não há benefício em entregar alguns cálculos curtos da CPU para a GPU, porque os custos de instalação e desmontagem irão inundar o tempo necessário para fazer o cálculo.

A linha inferior é que as GPUs são úteis quando você tem muitas (como em centenas ou milhares) de cópias de um cálculo longo que pode ser calculado em paralelo. Tarefas típicas para as quais isso é comum são computação científica, codificação de vídeo e renderização de imagem. Para um aplicativo como um editor de texto, a única função em que uma GPU pode ser útil é renderizar o tipo na tela.

Charles E. Grant
fonte
O suporte de precisão dupla faz parte do Shader Model 5 e a AMD / ATI também.
Ben Voigt
@ Ben, obrigado pela correção. Eu removi a declaração incorreta.
Charles E. Grant
11

As GPUs não são processadores generalistas da mesma forma que as CPUs. Eles se especializam em fazer uma coisa muito específica - aplicar o mesmo código a uma grande quantidade de dados - e fazem isso muito, muito bem, muito melhor do que uma CPU. Mas a maioria das aplicações não se aplica ao mesmo código a uma grande quantidade de dados; trata-se de um loop de eventos: aguardando entrada, lendo a entrada, atuando nela e, em seguida, aguardando mais entradas. Esse é um processo bastante serial, e as GPUs são péssimas em "serial".

Quando você tiver uma grande quantidade de dados que precisa processar e cada item puder ser processado em paralelo, independentemente dos outros, vá em frente e envie-o para a GPU. Mas não pense nisso como "o novo paradigma" no qual tudo deve ser espremido.

Esta pergunta está marcada como "otimização", então lembre-se de tratá-la como uma. Aplique a otimização da GPU onde os testes e os perfis revelam que a otimização é necessária e a natureza da tarefa é tal que a otimização da GPU pode ser aplicada. Caso contrário, não se preocupe, pois isso seria uma otimização prematura ou incorreta, o que causa mais problemas do que conserta.

Mason Wheeler
fonte
8

A resposta simples é que uma GPU funciona melhor quando você precisa fazer um cálculo bastante pequeno e bastante simples em cada um de um número muito grande de itens. Para realizar muito dessa maneira, o cálculo para cada item deve ser independente do cálculo para os outros itens. Se houver (normalmente) alguma dependência entre um item e outro, você geralmente precisa descobrir uma maneira de quebrá-lo antes de tirar muito proveito da execução desse código na GPU. Se a dependência não puder ser quebrada ou exigir muito trabalho para quebrar, o código poderá ser executado mais rapidamente na CPU.

A maioria das CPUs atuais também suporta vários tipos de operações que as GPUs atuais simplesmente não tentam oferecer suporte (por exemplo, proteção de memória para multitarefa).

Olhando para isso de uma direção um pouco diferente, as CPUs foram (em grande parte) projetadas para serem razoavelmente convenientes para os programadores, e o pessoal do hardware fez o melhor (e o melhor que é!) Para criar hardware que mantém esse modelo conveniente para programador, mas ainda é executado o mais rápido possível.

As GPUs vêm das coisas na direção oposta: elas são projetadas para serem convenientes para o projetista de hardware, e coisas como o OpenCL tentaram fornecer o modelo de programação o mais razoável possível, dadas as restrições do hardware.

Escrever código para rodar em uma GPU normalmente leva mais tempo e esforço (por isso custa mais) do que fazer o mesmo na CPU. Como tal, fazer isso principalmente faz sentido quando / se:

  1. O problema é tão paralelo que você pode esperar um grande ganho com o mínimo esforço, ou
  2. O ganho de velocidade é tão importante que justifica muito trabalho extra.

Existem algumas possibilidades óbvias para cada uma - mas um grande número de aplicativos claramente não chega nem perto de nenhum deles. Eu ficaria surpreso ao ver (por exemplo) um aplicativo CRUD em execução em uma GPU em breve (e se acontecer, provavelmente acontecerá porque alguém partiu com esse objetivo exato em mente, não necessariamente algo parecido com um ótimo relação custo / benefício).

A realidade é que, para muitos aplicativos (sou tentado a dizer "a maioria"), uma CPU típica é muito mais do que rápida o suficiente, e a conveniência da programação (levando a coisas como desenvolvimento mais fácil de novos recursos) é muito mais importante do que velocidade de execução.

Jerry Coffin
fonte
3

você seria capaz de fazer muitos cálculos ao mesmo tempo e realmente melhorar a velocidade.

melhorar a velocidade? E daí? No ano passado, só me lembro uma ou duas vezes quando era necessário. Na maioria das vezes me pediram para modificar ou corrigir a lógica, ajustar uma fonte de dados diferente, melhorar a interação do usuário etc. A única velocidade que os clientes estavam interessados ​​nesses casos era a velocidade de fazer uma alteração. "Libere o novo recurso em um mês, ou melhor ainda - em duas semanas".

Não me interpretem mal - como codificador, eu gosto de apertar os carrapatos da CPU completamente. É apenas que essa arte normalmente não está em alta demanda.

Ainda existem certos casos em que o processamento serial ainda é melhor, mais rápido e / ou mais eficiente que o paralelo?

Eu diria que existem muitos casos. O processamento serial é mais simples que paralelo, o que o torna mais eficiente em todos os casos em que a velocidade não é um requisito crítico. O processamento serial permite uma implementação mais fácil de lógica complicada e interface do usuário, é mais fácil especificar e testar, manter e alterar.

Como regra, o processamento serial permite uma expressão mais clara da intenção do programador e uma leitura mais fácil do código. Eu diria que economiza o recurso mais precioso e escasso - o cérebro do programador.

mosquito
fonte
2

As CPUs são ainda mais versáteis. Por exemplo, as GPUs são mais eficientes que as CPUs na precisão única, mas não na precisão dupla. Há muito mais bibliotecas para CPUs do que para GPUs.

quant_dev
fonte
3
Você pode entrar em mais detalhes? Você forneceu três declarações sem informações ou explicações sobre a veracidade delas.
Bem, a falta de eficiência cálculos de precisão dupla é de conhecimento comum: en.wikipedia.org/wiki/GPGPU
quant_dev
@quant: Suas informações estão desatualizadas há pelo menos 2 anos: 544 GigaFLOPS é muito mais rápido que qualquer CPU convencional.
Ben Voigt
@ Ben Não vejo onde seu link menciona o desempenho de precisão dupla.
quant_dev 12/09
@quant: awurl.com/Tt7LAX8lH
Ben Voigt
2

A regra simples é: se o que você está fazendo pode ser expresso em termos de construções da álgebra linear e é de tempo crítico, faça-o na GPU, caso contrário, use a CPU.

As GPUs não são como um grande número de CPUs, elas têm características de desempenho muito diferentes.

dan_waterworth
fonte
Se for "tempo crítico", você provavelmente não terá tempo para reconfigurar a GPU para um sombreador de computação e fazer upload dos dados. São os grandes problemas que mais beneficiam.
Ben Voigt
@ Ben, acho que temos definições diferentes de "tempo crítico", o que quero dizer é que o cálculo está no caminho crítico por uma quantidade significativa de tempo.
dan_waterworth
1

Se você precisa de processamento de números brutos, as GPUs são o caminho a percorrer. No entanto, todas essas ULAs significam que há menos transistores dedicados ao controle de circuitos de fluxo (ramificação). Portanto, se você precisar escrever algo que exija muito fluxo de controle complexo, muitos condicionais etc., a CPU será mais rápida.

Alex
fonte