1. Vários conceitos importantes sobre alta concorrência
1.1 síncrono e assíncrono
Primeiro de tudo, a sincronização e a assíncrona mencionada aqui se referem a aspectos de chamada de função/método.
Obviamente, uma chamada síncrona aguardará o retorno do método e uma chamada assíncrona retornará instantaneamente, mas uma chamada assíncrona retornará instantaneamente não significa que sua tarefa foi concluída. Ele configurará um encadeamento em segundo plano para continuar a tarefa.
1.2 Concorrência e paralelismo
A simultaneidade e o paralelismo são semelhantes na aparência externa. Como mostrado na figura, o paralelismo é quando duas tarefas são executadas simultaneamente, enquanto a concorrência é executar uma tarefa por vez e depois mudar para outra tarefa. Portanto, uma única CPU não pode ser paralela, só pode ser simultaneamente.
1.3 Zona crítica
A área crítica é usada para representar um recurso público ou dados compartilhados. Pode ser usado por vários threads, mas apenas um thread pode usá -lo por vez. Depois que o recurso de área crítica estiver ocupada, outros threads devem esperar se quiserem usar esse recurso.
1.4 Bloqueio e não bloqueio
Bloqueio e não bloqueio geralmente descrevem a influência mútua entre vários threads. Por exemplo, se um thread ocupar o recurso de área crítica, todos os outros threads que precisam desse recurso devem esperar nessa área crítica, e a espera fará com que o thread pendure. Isso está bloqueando. No momento, se o thread que ocupa o recurso não estiver disposto a liberar o recurso, todos os outros threads bloqueando nessa área crítica não poderão funcionar.
O não bloqueio permite que vários tópicos entrem na zona crítica ao mesmo tempo
Portanto, o desempenho do bloqueio geralmente não é muito bom. De acordo com as estatísticas gerais, se um thread for suspenso no nível do sistema operacional e fizer uma troca de contexto, geralmente leva 80.000 ciclos de tempo para fazer isso.
1.5 Deadlock, Fome, Live Lock
O chamado impasse refere-se a um bloqueio causado por recursos concorrentes ou se comunicando durante o processo de execução de dois ou mais processos. Sem forças externas, elas não serão capazes de avançar. Neste momento, o sistema é chamado de impasse ou o sistema possui um impasse. Esses processos que estão sempre esperando um pelo outro são chamados de processos de impasse. Assim como os carros na figura abaixo, querem avançar, mas ninguém pode avançar.
No entanto, embora o impasse seja um fenômeno ruim, é um problema estático. Uma vez que um impasse, o processo está preso e a taxa de ocupação da CPU também é 0. Ele não ocupará a CPU, será chamado. Relativamente falando, é relativamente fácil descobrir e analisar.
Correspondente ao impasse é a trava ao vivo.
Live Lock significa que as coisas 1 posso usar recursos, mas permite que outras coisas usem os recursos primeiro; As coisas 2 podem usar recursos, mas também permite que outras coisas usem os recursos primeiro, para que ambos tenham sido humildes e não possam usar recursos.
Por exemplo, é como se você conhecesse alguém na rua, que está andando na direção oposta de você e encontrando você de frente, todos querem se deixar ir. Você se mudou para a esquerda e ele se mudou para a esquerda, mas os dois ainda não podiam ir para lá. Neste momento, você se move para a direita e ele se move para a direita e continua dessa maneira.
Quando um thread obtém um recurso, ele descobre que outros threads também pensam nesse recurso porque não obtiveram todos os recursos; portanto, para evitar o deadlock, eles desistem de todos os recursos que possuem. Se outro thread fizer a mesma coisa, eles precisam dos mesmos recursos, como um recurso, B possui um recurso B e, depois de desistir do recurso, A obtém recurso B e B obtém um recurso, e isso é repetido, ocorre uma trava ao vivo.
As fechaduras vivas são mais difíceis de detectar do que os impasse, porque as fechaduras ao vivo são um processo dinâmico.
A fome significa que um ou mais threads não podem obter os recursos necessários por vários motivos, o que os torna incapazes de executar.
1.6 Nível de simultaneidade
Níveis de simultaneidade: bloqueio e não bloqueio (o não bloqueio é dividido em sem barreira, sem trava e sem espera)
1.6.1 Bloqueio
Quando um tópico entra na seção crítica, outros threads devem esperar
1.6.2 Acessibilidade
Comparado com o agendamento sem bloqueio, o agendamento de bloqueio é uma estratégia pessimista, que acredita que a modificação de dados juntos provavelmente tornará os dados ruins. Em vez de bloquear a programação, é uma estratégia otimista, que acredita que a modificação de dados pode não tornar necessariamente os dados ruins. No entanto, é uma estratégia de ampla entrada e saída estrita. Quando descobre que um processo possui concorrência e conflitos de dados na área crítica, o método de agendamento sem barreira reverte os dados.
Neste método de agendamento sem barreira, todos os threads são equivalentes a tirar um instantâneo de um sistema. Eles continuarão tentando tirar os instantâneos até serem válidos.
1.6.3 sem trava
É acessível
Verifique se há um tópico que pode ganhar
Comparado com a acessibilidade, a acessibilidade não garante que as operações possam ser concluídas quando houver concorrência, porque se encontrar conflitos em cada operação, continuará tentando. Se os threads na área crítica interferirem entre si, isso fará com que todos os threads fiquem presos na área crítica e, em seguida, o desempenho do sistema terá um grande impacto.
O Lockless adiciona uma nova condição para garantir que um tópico possa ganhar cada competição, que resolve o problema da frequência de barreira. Pelo menos garante que todos os threads sejam executados sem problemas.
O código a seguir é um código de cálculo sem trava típico em Java
Lockless é comum em java
while (! atomicvar.compareandset (localvar, localvar+1)) {localvar = atomicvar.get (); }1.6.4 Sem espera
Sem trava
Todos os tópicos devem ser concluídos dentro de uma etapa limitada
Sem fome
Primeiro de tudo, a premissa de nenhuma espera é com base na trava. A trava livre garante apenas que deve haver entrada e saída na área crítica. No entanto, se a prioridade da entrada for muito alta, alguns fios com baixa prioridade na área crítica podem estar com fome e não podem deixar a área crítica. Então, nenhuma espera resolverá esse problema, o que garante que todos os tópicos sejam concluídos em uma etapa limitada e, naturalmente, não há fome.
Nenhuma espera é o nível mais alto de paralelismo, que pode permitir que esse sistema atinja o estado ideal.
Casos típicos sem esperar:
Se houver apenas threads de leitura e nenhum threads, isso deve ser sem esperar.
Se houver threads de leitura e threads de gravação e antes de cada thread de gravação, copie os dados e modifique a cópia em vez de modificar os dados originais, porque não há conflito na modificação da cópia, o processo de modificação também será sem esperar. A sincronização final é apenas para substituir os dados escritos.
Como o requisito sem espera é relativamente alto e é difícil de implementar, o bloqueio será usado mais amplamente.
2. Duas leis importantes sobre paralelismo
Ambas as leis estão relacionadas à taxa de aceleração
2.1 Lei de Amdahl
Defina a fórmula de cálculo e o limite superior teórico da taxa de aceleração após a paralelização dos sistemas seriais
Razão de aceleração Definição: Razão de aceleração = tempo consumido do sistema antes da otimização / tempo consumido após a otimização
Por exemplo:
Índice de aceleração = tempo consumido do sistema antes da otimização / tempo consumido após a otimização = 500 /400 = 1,25
Esse teorema mostra que o aumento do número de processadores da CPU não desempenha necessariamente um papel eficaz no aumento da proporção de módulos paralelos no sistema. Somente aumentando razoavelmente o número de processadores paralelos, a taxa de aceleração máxima pode ser obtida com o menor investimento.
2.2 Lei de Gustafson
Explique a relação entre o número de processadores, proporção serial e relação de aceleração
Então a taxa de aceleração = nf (n-1) // o processo de derivação é omitido
Enquanto houver paralelização suficiente, a taxa de aceleração é proporcional ao número de CPUs.