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:
- O problema é tão paralelo que você pode esperar um grande ganho com o mínimo esforço, ou
- 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.