O que é melhor para um aplicativo Java Web: mais núcleos de CPU ou maior velocidade de clock?

O que é melhor para um aplicativo Java Web: mais núcleos de CPU ou maior velocidade de clock?

Não tenho certeza se serverfault é o lugar certo para perguntar isso, mas me pergunto que escolha você faria se tivesse que selecionar um novo tipo de CPU para seu aplicativo Java Web:

a) uma CPU com 32 núcleos e velocidade de clock de 2,5 Ghz

ou

b) uma CPU com 8 núcleos, mas velocidade de clock de 3,8 Ghz

Dado o fato de que cada solicitação HTTP recebida do aplicativo da Web é atendida por um encadeamento Java livre, pode fazer sentido escolher a), porque você pode processar quatro vezes mais solicitações HTTP ao mesmo tempo. Porém, por outro lado, a CPU b) pode finalizar o processamento de uma única solicitação HTTP muito mais rápido...

O que você acha?

Notas laterais:

  • tem que ser uma máquina física, VMs ou soluções em nuvem não são uma opção neste caso
  • RAM não é importante, o servidor terá 512GB de RAM no final
  • Cache: o aplicativo web Java apresenta uma extensa estrutura de cache, então a escolha está realmente nas CPUs.

Responder1

tldr;A verdadeira resposta é provavelmente "mais RAM", mas como você fez sua pergunta, a resposta é, claro, depende. Então, novamente, 32 núcleos a 2,5 GHz quase certamente superarão 8 núcleos a 3,8 GHz - são 4 vezes mais núcleos versus um clock 1,5 vezes mais rápido. Não é uma luta muito justa.

Alguns fatores que você deve considerar são o tempo de resposta da transação, usuários simultâneos e arquitetura do aplicativo.

Tempo de resposta da transação Se o seu aplicativo Java responde à maioria das solicitações em alguns milissegundos, ter mais núcleos para lidar com mais solicitações simultâneas é provavelmente o caminho a percorrer. Mas se o seu aplicativo lida principalmente com transações mais complexas e de execução mais longa, ele pode se beneficiar de núcleos mais rápidos. (ou talvez não - veja abaixo)

Usuários e solicitações simultâneas Se o seu aplicativo Java receber um grande número de solicitações simultâneas, mais núcleos provavelmente ajudarão. Se você não tiver tantas solicitações simultâneas, poderá estar pagando apenas por vários núcleos ociosos extras.

Arquitetura de aplicativo Essas solicitações de longa duração que mencionei não se beneficiarão muito com núcleos mais rápidos se o servidor de aplicativos gastar a maior parte do tempo de transação aguardando respostas de serviços da web, bancos de dados, kafaka/mq/etc. Já vi muitos aplicativos com transações de 20 a 30 segundos que gastam apenas uma pequena parte do tempo de resposta processando no próprio aplicativo e o restante do tempo aguardando respostas de bancos de dados e serviços da Web.

Você também deve garantir que as diferentes partes do seu aplicativo se encaixem bem. Não adianta muito ter 32 ou 64 threads, cada um lidando com uma solicitação, todos na fila, aguardando uma das 10 conexões no pool JDBC, também conhecido como o porco em um problema de python. Um pouco de planejamento e design agora economizará muitas soluções de problemas de desempenho mais tarde.

Uma última coisa: quais CPUs você poderia comparar? A CPU de 32 núcleos de 2,5 GHz mais barata que posso encontrar custa pelo menos 3 ou 4 vezes mais do que qualquer CPU de 8 núcleos de 3,8 GHz.

Responder2

Supondo que seu servidor web Java esteja configurado adequadamente, você deve optar por mais núcleos.

Ainda existem dependências, como semáforos, acessos simultâneos que ainda terão algumas threads aguardando, seja qual for o número de núcleos ou velocidade. Mas é melhor quando é gerenciado pela CPU (núcleos) do que pelo sistema operacional (multithreading).

De qualquer forma, 32 núcleos a 2,5 GHz irão lidar com mais threads e melhor do que 8 núcleos a 3,8 GHz.

Além disso, o calor produzido pela CPU depende da frequência (entre outras coisas) e isso não é linear. Ou seja, 3,8 Ghz gerará mais calor do que 3,8/2,5 x (deve ser confirmado com base nos tipos/marcas exatas de CPUs... muitos sites oferecem informações detalhadas).

Responder3

Você nos diz que a solicitação leva cerca de 100-200 ms para ser executada e que é principalmente tempo de processamento (embora seja difícil separar o que é a execução real da CPU do que é, na realidade, acesso à memória), muito pouca E/S, espera por bancos de dados, etc.

Você teria que avaliar quanto tempo realmente leva em cada uma das duas CPUs, mas vamos supor que sejam necessários 150 ms na CPU mais lenta (com 32 núcleos) e 100 ms na mais rápida (com apenas 8 núcleos).

Então a primeira CPU seria capaz de lidar com até 32/0,15 = 213 solicitações por segundo.

A segunda CPU seria capaz de lidar com até 8/0,1 = 80 solicitações por segundo.

Portanto, a grande questão é: quantas solicitações por segundo você espera? Se você não estiver perto de dezenas de solicitações por segundo, não precisará da primeira CPU, e a segunda proporcionará um tempo de execução mais rápido em cada solicitação. Se você precisar de mais de 100 solicitações por segundo, a primeira fará sentido (ou provavelmente fará mais sentido ter mais de um servidor).

Observe que essas são estimativas do tipo back-of-the-envelope. A única maneira de ter certeza é avaliar cada um dos servidores com uma carga real. Como afirmado acima, CPUs rápidas ou CPUs com muitos núcleos podem rapidamente ficar sem acesso à memória. O tamanho dos vários caches da CPU é muito importante aqui, assim como o “conjunto de trabalho” de cada solicitação. E isso considerando o trabalho verdadeiramente vinculado à CPU, sem chamadas de sistema, sem recursos compartilhados, sem E/S...

Responder4

Nota preliminar
Eu gostaria de segundo@PossivelmenteUsefulProbablyNotderesposta definitivamente útil.

tldr; A verdadeira resposta é provavelmente “mais RAM”

Especialmente este ponto.

Embargo
Não é tanto um administrador per sé.
Mais uma perspectiva de engenharia de software, talvez.

Nenhuma alternativa à medição

O que nós sabemos
Então, a máquina é

  • vou executar uma espécie de aplicativo de back-end baseado em Java (empresarial?)
  • publicamente (dentro de algum contexto considerável, de qualquer maneira) expor uma API HTTP que trata de solicitações de clientes
  • presumivelmente com alguma forma de banco de dados anexado
  • é descrito de outra forma como não muito limitado por E/S
  • não depende da disponibilidade, latência ou rendimento de serviços de terceiros

Não é uma imagem tão vaga, o OP está pintando. Mas, ao mesmo tempo, longe de haver dados suficientes para dar uma respostarelativo à situação individual dos PO.
Claro, 32 núcleos a 2/3 da velocidade do clock sãoprovávelpara ter um desempenho melhor do que 1/4 dos núcleos com uma vantagem de velocidade comparativamente pequena. Claro, o calor gerado não funciona bem com velocidades de clock acima do limite de 4 GHz. E claro, se eu tivesse que colocar meus ovos cegamente na mesma cesta, eu escolheria os 32 núcleos em qualquer dia da semana.

O que não sabemos
Demais, ainda.

No entanto,além dessas verdades simples, eu seria muito cético em relação a uma tentativa hipotética de uma resposta mais concreta e objetiva. Se simfor possível (e você tem muitos motivos para permanecer convencido de que as operações por unidade de tempo são uma preocupação válida), coloque as mãos no hardware no qual pretende executar o sistema,meça e teste, de ponta a ponta.
Umdecisão informadaenvolve relevanteedados críveis.

OP escreveu: RAM não é importante

Na grande maioria dos casos, a memóriaéo gargalo.

Concedido, o OPestá perguntando principalmente sobreNúcleos da CPU versus velocidade do clocke assim a memória aparece à margem do off-topic.

Eu não acho que seja, no entanto. Para mim, parece muito mais provável que a questão seja baseada em uma premissa falsa. Agora, não me interpretem mal, @OP, sua pergunta está no assunto, bem formulada e sua preocupação é obviamente real. Simplesmente não estou convencido de que a resposta para qual CPU teria um desempenho "melhor" no seu caso de uso seja relevante (para você).

Por que a memória é importante (para a CPU)

A memória principal éterrivelmente lento.
Historicamente, em comparação com o disco rígido, tendemos a pensar na RAM como “o tipo rápido de armazenamento”. No contexto dessa comparação, ainda é verdade. No entanto, ao longo das últimas décadas, as velocidades dos processadores cresceram consistentemente a uma taxa significativamente mais rápida do que o desempenho da DRAM. Este desenvolvimento ao longo do tempo levou ao que é comumente conhecido como"Lacuna de memória do processador".

A lacuna entre as velocidades do processador e da memória

A diferença entre as velocidades do processador e da memória (fonte: Carlos Carvalho, Departamento de Informática, Universidade do Minho)

Buscando uma linha de cacheda memória principal para um registro da CPU ocupa aproximadamente aproximadamente 100 ciclos de clockde tempo. Durante esse período, seu sistema operacional reportará um dos dois threads de hardware em um dos 4 (?) núcleos de sua arquitetura x86 comoocupado.
Na medida em quedisponibilidadedeste segmento de hardware está em causa, seu sistema operacional não está mentindo, eleestá ocupado esperando. Entretanto, a própria unidade de processamento, desconsiderando a linha de cache que está rastejando em sua direção, éde fato ocioso.
Nenhuma instrução/operação/cálculo realizado durante esse período.

+----------+---------------+---------------------------------------------------------------------------------------------------+
|  Type of |    size of    |                                Latency due to fetching a cache line                               |
| mem / op |     cache     +--------+--------+------------+--------------------------------------------------------------------+
|          |   (register)  |  clock |  real  | normalized |                            now I feel it                           |
|          |               | cycles |  time  |            |                                                                    |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
|   tick   |      16KB     |    1   | 0.25ns |     1s     |             Dinner is already served. Sit down, enjoy.             |
|          | *the* 64 Bits |        |        |            |                                                                    |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
|    L1    |      64KB     |    4   |   1ns  |     4s     |               Preparations are done, food's cooking.               |
|          |               |        |        |            |                 Want a cold one to bridge the gap?                 |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
|    L2    |     2048KB    |   11   |  ~3ns  |     12s    |        Would you be so kind as to help me dice the broccoli?       |
|          |               |        |        |            |    If you want a beer, you will have to go to the corner store.    |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
|    L3    |     8192KB    |   39   |  ~10ns |     40s    |    The car is in the shop, you'll have to get groceries by bike.   |
|          |               |        |        |            |             Also, food ain't gonna cook itself, buddy.             |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
|   DRAM   |     ~20GB     |   107  |  ~30ns |    2min    |      First year of college. First day of the holiday weekend.      |
|          |               |        |        |            |         Snow storm. The roommate's are with their families.        |
|          |               |        |        |            | You have a piece of toast, two cigarettes and 3 days ahead of you. |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+

Valores de latência dos Core-i7-9XXchips da série (fonte: Scott Meyers, 2010)

Resultado final Se a medição adequada não for uma opção, em vez de debater núcleos versus velocidade de clock, oo investimento mais seguro para o excesso de orçamento de hardware está no tamanho do cache da CPU.

Portanto, se a memória mantém regularmente threads de hardware individuais ociosos, certamente mais núcleos ~cow bell~ são a solução?

Em teoria, se o software estivesse pronto, multi/hyper-threadingpoderiaseja rápido

Suponha que você esteja analisando suas declarações fiscais (por exemplo) dos últimos anos, digamos, 8 anos de dados no total. Você mantém 12 valores mensais (colunas) por ano (linha).

Agora, um byte pode conter 256 valores individuais (já que seus 8 dígitos binários individuais, podem assumir 2 estados cada, o que resulta em 8^2 = 256permutações de estados distintos. Independentemente da moeda, 256 parece um pouco inferior para ser capaz de representar o limite superior dos valores salariais. Além disso, por uma questão de argumentação, vamos assumir que a menor denominação ("centavos") não importa (todos ganham valores inteiros da denominação principal). a alta administração e a força de trabalho regular e, portanto, mantém os poucos selecionados em um sistema de contabilidade totalmente diferente.

Então, neste cenário simplificado, vamos supor que o dobro da quantidade de espaço de memória acima mencionada, ou seja, 2 bytes (ou uma “meia palavra”), quando utilizada na unsignedforma, ou seja, representando a faixa de [0, 2^16 = 65536), seja suficiente para expressar todos os valores salariais mensais do funcionário.

Portanto, na linguagem/RDBS/OS de sua escolha, você agora mantém uma matriz (alguma estrutura de dados bidimensional, uma "lista de listas") com valores de tamanho de dados uniforme (2 bytes/16 bits).
Em, digamos, C++, isso seria um arquivo std::vector<std::vector<uint16_t>>. Suponho que você também usaria um of em Java vector.vectorshort

Agora, aqui está opergunta do prêmio:
Digamos que você queira ajustar os valores desses 8 anos pela inflação (ou algum outro motivo arbitrário para escrever no espaço de endereço). Estamos observando uma distribuição uniforme de valores de 16 bits. Você precisará visitar cada valor da matriz uma vez, lê-lo, modificá-lo e depois gravá-lo no espaço de endereço.
Importa como você atravessa os dados?

A resposta é:sim muito mesmo. Se você iterar primeiro nas linhas (a estrutura de dados interna), obterá uma escalabilidade quase perfeita em um ambiente de execução simultânea. Aqui, um thread extra e, portanto, metade dos dados em um e a outra metade no outro, executarão seu trabalho duas vezes mais rápido. 4 tópicos? 4 vezes o ganho de desempenho.
Se, no entanto, você decidir fazer as colunas primeiro, dois threads executarão sua tarefasignificativamente mais lento. Você precisará de aproximadamente 10 threads paralelos de execução apenas para mitigar (!) O efeito negativo que a escolha da direção principal de passagem acabou de ter. E enquanto seu código fosse executado em um único thread de execução, você não poderia medir a diferença.

+------+------+------+------+------+------+------+
| Year |  Jan |  Feb | Mar  | Apr  | ...  | Dec  |
+------+------+------+------+------+------+------+
| 2019 | 8500 | 9000 | 9000 | 9000 | 9000 | 9000 | <--- contiguous in memory
+------+------+------+------+------+------+------+
| 2018 | 8500 | 8500 | 8500 | 8500 | 8500 | 8500 | <--- 12 * 16Bit (2Byte)
+------+------+------+------+------+------+------+
| 2017 | 8500 | 8500 | 8500 | 8500 | 8500 | 8500 | <--- 3 * (4 * 16Bit = 64Bit (8Byte) 
+------+------+------+------+------+------+------+
| ...  | 8500 | 7500 | 7500 | 7500 | 7500 | 7500 | <--- 3 cache lines
+------+------+------+------+------+------+------+
| 2011 | 7500 | 7200 | 7200 | 7200 | 7200 | 7200 | <--- 3 lines, likely from the same
+------+------+------+------+------+------+------+      virtual memory page, described by 
                                                        the same page block.

O OP escreveu: a) uma CPU com 32 núcleos e velocidade de clock de 2,5 Ghz
ou
b) uma CPU com 8 núcleos, mas velocidade de clock de 3,8 Ghz

Todo o resto sendo igual:

-->Considere o tamanho do cache, o tamanho da memória, os recursos especulativos de pré-busca do hardware e o software em execução que pode realmente aproveitar a paralelização, tudo mais importante que a velocidade do clock.

--> Mesmo sem depender de sistemas distribuídos de terceiros,certifique-se de que você realmente não está vinculado à E/S sob condições de produção.Se você precisa ter o hardware interno e não pode permitir que AWS/GCloud/Azure/Heroku/Whatever-XaaS-IsHipNow lide com esse problema, gaste nos SSDs em que você coloca seu banco de dados. Enquanto você faznãoSe você deseja que o banco de dados esteja ativo na mesma máquina física do seu aplicativo, certifique-se de que a distância da rede (meça a latência aqui também) seja a mais curta possível.

--> A escolha de uma biblioteca de servidor HTTP de "nível empresarial" renomada, avaliada e de primeira linha, que está além da sombra de qualquer dúvida, construída para simultaneidade, não é suficiente por si só. Certifique-se de que todas as bibliotecas de terceiros que você executa em suas rotas estejam. Certifique-se de que seu código interno também esteja.

VMs ou soluções em nuvem não são uma opção neste caso

Isso eu entendo.
Existem várias razões válidas.

tem que seramáquina física [...]
[...] CPU com 32 núcleos e velocidade de clock de 2,5 Ghz

Mas isso não é tanto.
Nem a AWS nem o Azure inventaram sistemas distribuídos, microclustering ou balanceamento de carga. É mais doloroso configurar em hardware bare metal e sem recursos do estilo MegaCorp, mas vocêpodeexecute uma malha distribuída de clusters K8 diretamente na sua sala de estar. E também existem ferramentas para verificações de integridade recorrentes e provisionamento automático em picos de carga para projetos auto-hospedados.

OP escreveu: RAM não é importante

Aqui está um cenário ~hipotético~ reproduzível: Habilite o zram como seu espaço de troca, porque a RAM é barata e não é importante e tudo mais. Agora execute uma tarefa constante e com uso intensivo de memória que não resulte exatamente em paginação frequente. Quando você atingir o ponto de inversão séria do LRU, seu ventilador ficará barulhento e os núcleos da CPU esquentarão - porque ele está ocupado lidando com o gerenciamento de memória (mover lixo para dentro e para fora do swap).

OP escreveu: RAM não é importante

Caso eu não tenha me expressado com clareza suficiente: acho que você deveria reconsiderar esta opinião.

DR;
32 núcleos.
Maisémelhorar.

informação relacionada