Qual é a diferença entre simultaneidade e paralelismo?
Exemplos são apreciados.
Qual é a diferença entre simultaneidade e paralelismo?
Exemplos são apreciados.
Respostas:
Simultaneidade é quando duas ou mais tarefas podem iniciar, executar e concluir em períodos de sobreposição. Isso não significa necessariamente que os dois estarão rodando no mesmo instante. Por exemplo, multitarefa em uma máquina de núcleo único.
Paralelismo é quando as tarefas literalmente são executadas ao mesmo tempo, por exemplo, em um processador multicore.
Citando o Guia de Programação Multithread da Sun :
Simultaneidade: uma condição que existe quando pelo menos dois threads estão progredindo. Uma forma mais generalizada de paralelismo que pode incluir a divisão do tempo como uma forma de paralelismo virtual.
Paralelismo: Uma condição que surge quando pelo menos dois threads estão sendo executados simultaneamente.
Existe confusão porque os significados do dicionário de ambas as palavras são quase os mesmos:
No entanto, a maneira como eles são usados em ciência da computação e programação são bem diferentes. Aqui está a minha interpretação:
Então, o que quero dizer com definições acima?
Vou esclarecer com uma analogia do mundo real. Digamos que você precise concluir duas tarefas muito importantes em um dia:
Agora, o problema é que a tarefa 1 exige que você vá a um escritório do governo extremamente burocrático que faz você esperar 4 horas seguidas para obter seu passaporte. Enquanto isso, a tarefa 2 é exigida pelo seu escritório e é uma tarefa crítica. Ambos devem ser concluídos em um dia específico.
Normalmente, você dirige para o escritório de passaportes por 2 horas, espera na fila por 4 horas, conclui a tarefa, volta duas horas, volta para casa, fica acordado por mais 5 horas e conclui a apresentação.
Mas você é esperto. Você planeja com antecedência. Você carrega um laptop e, enquanto espera na fila, começa a trabalhar na sua apresentação. Dessa forma, quando voltar para casa, você só precisará trabalhar 1 hora extra em vez de 5.
Nesse caso, as duas tarefas são feitas por você, apenas em pedaços. Você interrompeu a tarefa do passaporte enquanto esperava na fila e trabalhou na apresentação. Quando seu número foi chamado, você interrompeu a tarefa de apresentação e mudou para a tarefa de passaporte. A economia de tempo foi essencialmente possível devido à interrupção de ambas as tarefas.
A simultaneidade, IMO, pode ser entendida como a propriedade "isolamento" no ACID . Duas transações de banco de dados são consideradas isoladas se as sub-transações puderem ser executadas de todas as maneiras intercaladas e o resultado final for o mesmo, como se as duas tarefas fossem executadas seqüencialmente. Lembre-se de que, para as tarefas de passaporte e apresentação, você é o único executor .
Agora, já que você é um cara tão inteligente, obviamente você é superior e tem um assistente. Portanto, antes de sair para iniciar a tarefa do passaporte, ligue para ele e peça que ele prepare o primeiro rascunho da apresentação. Você passa o dia inteiro e termina a tarefa do passaporte, volta e vê seus e-mails e encontra o rascunho da apresentação. Ele fez um trabalho bastante sólido e, com algumas edições em mais 2 horas, você finaliza.
Agora, como seu assistente é tão inteligente quanto você, ele conseguiu trabalhar de forma independente , sem precisar pedir esclarecimentos constantemente. Assim, devido à independência das tarefas, elas foram executadas ao mesmo tempo por dois executores diferentes .
Ainda comigo? Bem...
Lembra da sua tarefa de passaporte, onde você tem que esperar na fila? Como é o seu passaporte, seu assistente não pode esperar na fila por você. Portanto, a tarefa do passaporte tem capacidade de interrupção (você pode interrompê-la enquanto espera na fila e continuar depois quando o número é chamado), mas não possui independência (o assistente não pode esperar em seu lugar).
Suponha que o escritório do governo tenha uma verificação de segurança para entrar nas instalações. Aqui, você deve remover todos os dispositivos eletrônicos e enviá-los aos oficiais, e eles somente os devolverão após a conclusão da tarefa.
Nesse caso, a tarefa do passaporte não é independente nem interruptível . Mesmo se você estiver esperando na fila, não poderá trabalhar em outra coisa porque não possui o equipamento necessário.
Da mesma forma, diga que a apresentação é de natureza tão matemática que você precisa de 100% de concentração por pelo menos 5 horas. Você não pode fazer isso enquanto espera na fila pela tarefa de passaporte, mesmo que tenha seu laptop com você.
Nesse caso, a tarefa de apresentação é independente (você ou seu assistente podem dedicar 5 horas de esforço concentrado), mas não podem ser interrompidos .
Agora, diga que, além de atribuir seu assistente à apresentação, você também carrega um laptop para a tarefa do passaporte. Enquanto espera na fila, você vê que seu assistente criou os 10 primeiros slides em um deck compartilhado. Você envia comentários sobre o trabalho dele com algumas correções. Mais tarde, quando você voltar para casa, em vez de duas horas para finalizar o rascunho, precisará de apenas 15 minutos.
Isso foi possível porque a tarefa de apresentação tem independência (qualquer um de vocês pode fazê-lo) e interrupção (você pode pará-lo e continuar mais tarde). Então, você executou simultaneamente as duas tarefas e executou a tarefa de apresentação em paralelo.
Digamos que, além de ser excessivamente burocrático, o escritório do governo é corrupto. Assim, você pode mostrar sua identificação, inseri-la, começar a esperar na fila para que seu número seja chamado, subornar um guarda e outra pessoa para manter sua posição na fila, sair furtivamente, voltar antes que seu número seja chamado e retomar a espera você mesmo.
Nesse caso, você pode executar as tarefas de passaporte e apresentação simultaneamente e em paralelo. Você pode se esgueirar e sua posição é ocupada pelo seu assistente. Ambos podem trabalhar na apresentação, etc.
No mundo da computação, aqui estão exemplos de cenários típicos de cada um desses casos:
Se você perceber por que Rob Pike está dizendo que a concorrência é melhor, você precisa entender que o motivo é esse. Você tem uma tarefa muito longa, na qual existem vários períodos de espera em que você espera por algumas operações externas, como leitura de arquivo, download da rede. Em sua palestra, tudo o que ele está dizendo é: "basta terminar essa longa tarefa seqüencial para que você possa fazer algo útil enquanto espera". É por isso que ele fala sobre diferentes organizações com vários esquilos.
Agora, a força do Go vem de facilitar essa quebra com go
palavras - chave e canais. Além disso, existe um excelente suporte subjacente no tempo de execução para agendar essas goroutines.
Mas essencialmente, a concorrência é melhor que o paralelismo?
Maçãs são melhores que laranjas?
Gosto da palestra de Rob Pike: simultaneidade não é paralelismo (é melhor!) (Slides) ()
Rob geralmente fala sobre Go e geralmente aborda a questão da simultaneidade versus paralelismo em uma explicação visual e intuitiva! Aqui está um breve resumo:
Tarefa: Vamos gravar uma pilha de manuais obsoletos! Um por vez!
Simultaneidade: Existem muitas decomposições simultâneas da tarefa! Um exemplo:
Paralelismo: a configuração anterior ocorre em paralelo se houver pelo menos 2 esquilos trabalhando ao mesmo tempo ou não.
Para adicionar o que outros disseram:
A simultaneidade é como ter um malabarista fazendo malabarismos com muitas bolas. Independentemente de como isso pareça, o malabarista está apenas pegando / jogando uma bola por mão de cada vez. Paralelismo é ter vários malabaristas manipulando bolas simultaneamente.
Digamos que você tenha um programa que tenha dois threads. O programa pode ser executado de duas maneiras:
Concurrency Concurrency + parallelism
(Single-Core CPU) (Multi-Core CPU)
___ ___ ___
|th1| |th1|th2|
| | | |___|
|___|___ | |___
|th2| |___|th2|
___|___| ___|___|
|th1| |th1|
|___|___ | |___
|th2| | |th2|
Nos dois casos, temos simultaneidade pelo simples fato de termos mais de um encadeamento em execução.
Se rodássemos esse programa em um computador com um único núcleo de CPU, o sistema operacional alternaria entre os dois threads, permitindo que um thread fosse executado por vez.
Se rodássemos este programa em um computador com uma CPU com vários núcleos, poderíamos executar os dois threads em paralelo - lado a lado, exatamente ao mesmo tempo.
Simultaneidade: se dois ou mais problemas forem resolvidos por um único processador.
Paralelismo: se um problema for resolvido por vários processadores.
Vou tentar explicar com um exemplo interessante e fácil de entender. :)
Suponha que uma organização organize um torneio de xadrez onde 10 jogadores ( com habilidades iguais de jogar xadrez ) desafiarão um campeão profissional de xadrez. E como o xadrez é um jogo 1: 1, os organizadores precisam realizar 10 jogos com eficiência no tempo, para que possam terminar o evento o mais rápido possível.
Esperamos que os seguintes cenários descrevam facilmente várias maneiras de conduzir esses 10 jogos:
1) SÉRIE - digamos que o profissional brinca com cada pessoa uma a uma, ou seja, inicia e termina o jogo com uma pessoa e depois inicia o próximo jogo com a próxima pessoa e assim por diante. Em outras palavras, eles decidiram conduzir os jogos sequencialmente. Portanto, se um jogo leva 10 minutos para ser concluído, 10 jogos levam 100 minutos, também assuma que a transição de um jogo para outro leva 6 segundos e, para 10 jogos, serão 54 segundos (aproximadamente 1 minuto).
portanto, todo o evento será concluído em aproximadamente 101 minutos ( PIOR ABORDAGEM )
2) CONCORRENTE - digamos que o profissional joga sua vez e passa para o próximo jogador, para que todos os 10 jogadores estejam jogando simultaneamente, mas o jogador profissional não está com duas pessoas por vez, ele joga sua vez e passa para a próxima pessoa. Agora, assuma que o jogador profissional leva 6 segundos para jogar sua vez e também o tempo de transição do jogador profissional, com dois jogadores, é de 6 segundos, para que o tempo total de transição para retornar ao primeiro jogador seja de 1 min (10x6s). Portanto, quando ele voltar à primeira pessoa com quem o evento foi iniciado, 2 minutos se passaram (10xtime_per_turn_by_champion + 10xtransition_time = 2mins)
Supondo que todos os jogadores levem 45 segundos para completar seu turno, com base em 10 minutos por jogo do evento SERIAL no. de rodadas antes do jogo terminar 600 / (45 + 6) = 11 rodadas (aprox.)
Portanto, todo o evento será concluído aproximadamente em 11xtime_per_turn_by_player _ & _ champion + 11xtransition_time_across_10_players = 11x51 + 11x60sec = 561 + 660 = 1221sec = 20,35min (aproximadamente)
VEJA A MELHORIA de 101 minutos a 20,35 minutos ( MELHOR ABORDAGEM )
3) PARALELO - digamos que os organizadores obtenham fundos extras e, assim, decidiram convidar dois jogadores campeões profissionais (igualmente capazes) e dividiram o conjunto dos mesmos 10 jogadores (desafiantes) em dois grupos de 5 cada um e os atribuíram a dois campeões, ou seja, um agrupe cada um. Agora, o evento está progredindo em paralelo nesses dois sets, ou seja, pelo menos dois jogadores (um em cada grupo) estão jogando contra os dois jogadores profissionais em seu respectivo grupo.
No entanto, dentro do grupo, o jogador profissional leva um jogador de cada vez (ou seja, sequencialmente), portanto, sem qualquer cálculo, você pode deduzir facilmente que todo o evento será concluído aproximadamente em 101/2 = 50,5 minutos para concluir
VEJA A MELHORIA de 101 minutos a 50,5 minutos ( BOA ABORDAGEM )
4) CONCURRENTE + PARALELO - No cenário acima, digamos que os dois jogadores campeões joguem simultaneamente (leia o 2º ponto) com os 5 jogadores em seus respectivos grupos; agora, os jogos entre os grupos estão sendo executados em paralelo, mas dentro do grupo eles estão executando simultaneamente.
Portanto, os jogos em um grupo serão concluídos aproximadamente em 11xtime_per_turn_by_player _ & _ champion + 11xtransition_time_across_5_players = 11x51 + 11x30 = 600 + 330 = 930sec = 15.5mins (aproximadamente)
Portanto, todo o evento (envolvendo dois desses grupos paralelos) será concluído aproximadamente em 15,5 minutos
VEJA A MELHORIA de 101 minutos a 15,5 minutos ( MELHOR ABORDAGEM )
NOTA: no cenário acima, se você substituir 10 jogadores por 10 trabalhos semelhantes e dois jogadores profissionais com dois núcleos de CPU, novamente a seguinte ordem permanecerá verdadeira:
SÉRIE> PARALELO> CONCORRENTE> CONCORRENTE + PARALELO
(NOTA: esse pedido pode mudar para outros cenários, pois esse pedido depende muito da interdependência de trabalhos, da comunicação precisa de trabalhos em preto e branco e da transição de trabalhos em preto e branco)
Exemplo simples:
Simultâneo é: "Duas filas acessando uma máquina ATM"
Paralelo é: "Duas filas e dois caixas eletrônicos"
Imagine aprender uma nova linguagem de programação assistindo a um tutorial em vídeo. Você precisa pausar o vídeo, aplicar o que foi dito no código e continuar assistindo. Isso é simultaneidade.
Agora você é um programador profissional. E você gosta de ouvir música calma enquanto codifica. Isso é paralelismo.
Como Andrew Gerrand disse no GoLang Blog
Simultaneidade é lidar com muitas coisas ao mesmo tempo. Paralelismo é fazer muitas coisas ao mesmo tempo.
Aproveitar.
Eles resolvem problemas diferentes. A simultaneidade resolve o problema de ter escassos recursos da CPU e muitas tarefas. Portanto, você cria threads ou caminhos independentes de execução por meio do código para compartilhar o tempo no recurso escasso. Até recentemente, a concorrência dominava a discussão devido à disponibilidade da CPU.
O paralelismo resolve o problema de encontrar tarefas suficientes e tarefas apropriadas (que podem ser divididas corretamente) e distribuí-las por muitos recursos da CPU. O paralelismo sempre esteve presente, é claro, mas está chegando à vanguarda porque os processadores com vários núcleos são muito baratos.
concordância: múltiplos fluxos de execução com potencial para compartilhar recursos
Ex: dois threads competindo por uma porta de E / S.
paralelismo: dividir um problema em vários pedaços semelhantes.
Ex: analisando um arquivo grande executando dois processos em cada metade do arquivo.
A execução de programação simultânea possui 2 tipos: programação simultânea não paralela e programação simultânea paralela (também conhecida como paralelismo).
A principal diferença é que, para o olho humano, segmentos em simultâneo não paralelo parecem ser executados ao mesmo tempo, mas na realidade não. Em simultâneo não paralelo, os threads alternam rapidamente e se revezam para usar o processador através da redução de tempo. Enquanto no paralelismo há vários processadores disponíveis, vários threads podem ser executados em diferentes processadores ao mesmo tempo.
Referência: Introdução à simultaneidade em linguagens de programação
Paralelismo é a execução simultânea de processos em um multiple cores per CPU
ou multiple CPUs (on a single motherboard)
.
A simultaneidade ocorre quando o paralelismo é alcançado single core/CPU
usando algoritmos de agendamento que dividem o tempo da CPU (intervalo de tempo). Os processos são intercalados .
Unidades:
- 1 ou muitos núcleos em uma única CPU (praticamente todos os processadores modernos)
- 1 ou muitas CPUs em uma placa-mãe (pense em servidores da velha escola)
- 1 aplicativo é 1 programa (pense no navegador Chrome)
- 1 programa pode ter 1 ou vários processos (pense que cada guia do navegador Chrome é um processo)
- 1 processo pode ter 1 ou mais threads de 1 programa (guia Chrome reproduzindo vídeos do YouTube em 1 thread, outro thread gerado para a seção de comentários, outro para informações de login do usuário)
- Assim, 1 programa pode ter 1 ou mais threads de execução
- 1 processo é
thread(s)+allocated memory resources by OS
(pilha, registros, pilha, memória de classe)
Concorrência => Quando várias tarefas são executadas em períodos de sobreposição de recursos compartilhados (potencialmente maximizando a utilização dos recursos).
Paralelo => quando uma única tarefa é dividida em várias subtarefas independentes simples que podem ser executadas simultaneamente.
Pense nisso como filas de manutenção em que o servidor pode servir apenas o 1º trabalho em uma fila.
1 servidor, 1 fila de trabalhos (com 5 trabalhos) -> sem simultaneidade, sem paralelismo (apenas um trabalho está sendo atendido até a conclusão, o próximo trabalho na fila precisa aguardar até que o trabalho atendido seja concluído e não haja outro servidor para serviço)
1 servidor, 2 ou mais filas diferentes (com 5 trabalhos por fila) -> simultaneidade (como o servidor está compartilhando o tempo com todos os primeiros trabalhos em filas, igualmente ou ponderados), ainda não há paralelismo, pois a qualquer momento, existe um e apenas trabalho em manutenção.
2 ou mais servidores, uma Fila -> paralelismo (2 trabalhos realizados no mesmo instante), mas nenhuma simultaneidade (o servidor não está compartilhando tempo, o terceiro trabalho precisa aguardar até que um servidor seja concluído).
2 ou mais servidores, 2 ou mais filas diferentes -> simultaneidade e paralelismo
Em outras palavras, a simultaneidade está compartilhando tempo para concluir um trabalho, PODE levar o mesmo tempo para concluir seu trabalho, mas pelo menos é iniciado cedo. O importante é que os trabalhos podem ser divididos em trabalhos menores, o que permite a intercalação.
O paralelismo é alcançado com apenas mais CPUs, servidores, pessoas etc. que são executados em paralelo.
Lembre-se de que, se os recursos forem compartilhados, o puro paralelismo não poderá ser alcançado, mas é aqui que a simultaneidade teria o melhor uso prático, assumindo outro trabalho que não precisa desse recurso.
Vou oferecer uma resposta que conflite um pouco com algumas das respostas populares aqui. Na minha opinião, simultaneidade é um termo geral que inclui paralelismo. A simultaneidade se aplica a qualquer situação em que tarefas ou unidades de trabalho distintas se sobreponham no tempo. O paralelismo se aplica mais especificamente a situações em que unidades de trabalho distintas são avaliadas / executadas ao mesmo tempo físico. A razão de ser do paralelismo é acelerar o software que pode se beneficiar de vários recursos físicos de computação. O outro conceito principal que se encaixa na concorrência é a interatividade. Interatividadeaplica-se quando a sobreposição de tarefas é observável do mundo exterior. A razão de ser da interatividade é criar software que responda a entidades do mundo real como usuários, pares de rede, periféricos de hardware etc.
Paralelismo e interatividade são dimensões quase totalmente independentes da simultaneidade. Para um projeto em particular, os desenvolvedores podem se preocupar com um ou outro. Eles tendem a se confundir, principalmente porque a abominação que é fios fornece um primitivo razoavelmente conveniente para fazer as duas coisas.
Um pouco mais de detalhes sobre paralelismo :
O paralelismo existe em escalas muito pequenas (por exemplo, paralelismo em nível de instrução em processadores), escalas médias (por exemplo, processadores multicore) e grandes escalas (por exemplo, clusters de computação de alto desempenho). A pressão sobre os desenvolvedores de software para expor mais paralelismo em nível de encadeamento aumentou nos últimos anos, devido ao crescimento de processadores multicore. O paralelismo está intimamente ligado à noção de dependência . As dependências limitam a extensão em que o paralelismo pode ser alcançado; duas tarefas não podem ser executadas em paralelo se uma depender da outra (ignorando a especulação).
Existem muitos padrões e estruturas que os programadores usam para expressar paralelismo: pipelines, conjuntos de tarefas, operações agregadas em estruturas de dados ("matrizes paralelas").
Um pouco mais de detalhes sobre interatividade :
A maneira mais básica e comum de fazer interatividade é com eventos (ou seja, um loop de eventos e manipuladores / retornos de chamada). Para tarefas simples, os eventos são ótimos. A tentativa de realizar tarefas mais complexas com eventos entra no rasgo da pilha (também conhecido como inferno de retorno de chamada; inversão de controle). Quando você está cansado dos eventos, pode tentar coisas mais exóticas, como geradores, coroutines (também conhecidas como Async / Await) ou threads de cooperação.
Por amor a software confiável, não use threads se o que você deseja é interatividade.
Curmudgeonliness
Não gosto do slogan "concorrência simultânea não é paralelismo; é melhor". A concorrência não é nem melhor nem pior que o paralelismo. A simultaneidade inclui interatividade que não pode ser comparada de uma maneira melhor / pior com o paralelismo. É como dizer "o fluxo de controle é melhor que os dados".
Na eletrônica, serial e paralelo representam um tipo de topologia estática, determinando o comportamento real do circuito. Quando não há simultaneidade, o paralelismo é determinístico .
Para descrever fenômenos dinâmicos relacionados ao tempo , usamos os termos sequencial e simultâneo . Por exemplo, um determinado resultado pode ser obtido através de uma certa sequência de tarefas (por exemplo, uma receita). Quando estamos conversando com alguém, estamos produzindo uma sequência de palavras. No entanto, na realidade, muitos outros processos ocorrem no mesmo momento e, portanto, coincidem com o resultado real de uma determinada ação. Se muitas pessoas estão falando ao mesmo tempo, conversas simultâneas podem interferir em nossa sequência, mas os resultados dessa interferência não são conhecidos antecipadamente. A simultaneidade introduz indeterminação .
A caracterização serial / paralela e sequencial / simultânea são ortogonais. Um exemplo disso está na comunicação digital. Em um adaptador serial , uma mensagem digital é distribuída temporalmente (isto é, sequencialmente ) ao longo da mesma linha de comunicação (por exemplo, um fio). Em um adaptador paralelo , isso também é dividido em linhas de comunicação paralelas (por exemplo, muitos fios) e depois reconstruído na extremidade receptora.
Vamos imaginar um jogo, com 9 filhos. Se os dispusermos em cadeia, der uma mensagem no início e recebê-la no final, teremos uma comunicação serial. Mais palavras compõem a mensagem, consistindo em uma sequência de unidades de comunicação.
I like ice-cream so much. > X > X > X > X > X > X > X > X > X > ....
Este é um processo seqüencial reproduzido em uma infraestrutura serial .
Agora, vamos criar uma imagem para dividir as crianças em grupos de 3. Dividimos a frase em três partes, damos a primeira ao filho da linha à nossa esquerda, a segunda ao filho da linha central, etc.
I like ice-cream so much. > I like > X > X > X > .... > ....
> ice-cream > X > X > X > ....
> so much > X > X > X > ....
Este é um processo seqüencial reproduzido em uma infraestrutura paralela (embora ainda parcialmente serializada).
Nos dois casos, supondo que haja uma comunicação perfeita entre as crianças, o resultado é determinado previamente.
Se houver outras pessoas que conversam com o primeiro filho ao mesmo tempo que você, teremos processos simultâneos . Como não sabemos qual processo será considerado pela infraestrutura, o resultado final não é determinado previamente.
A simultaneidade é a forma generalizada de paralelismo. Por exemplo, um programa paralelo também pode ser chamado de concorrente, mas o inverso não é verdadeiro.
A execução simultânea é possível em um único processador (vários encadeamentos, gerenciados pelo planejador ou pelo conjunto de encadeamentos)
A execução paralela não é possível em um único processador, mas em vários processadores. (Um processo por processador)
A computação distribuída também é um tópico relacionado e também pode ser chamada de computação simultânea, mas o inverso não é verdadeiro, como o paralelismo.
Para detalhes, leia este documento de pesquisa Conceitos de Programação Concorrente
Gostei muito dessa representação gráfica de outra resposta - acho que ela responde à pergunta muito melhor do que muitas das respostas acima
Paralelismo x simultaneidade Quando dois threads estão sendo executados em paralelo, ambos estão sendo executados ao mesmo tempo. Por exemplo, se tivermos dois threads, A e B, sua execução paralela seria assim:
CPU 1: A ------------------------->
CPU 2: B ------------------------->
Quando dois threads estão sendo executados simultaneamente, sua execução se sobrepõe. A sobreposição pode ocorrer de duas maneiras: os threads estão executando ao mesmo tempo (ou seja, em paralelo, como acima) ou suas execuções estão sendo intercaladas no processador, da seguinte forma:
CPU 1: A -----------> B ----------> A -----------> B -------- ->
Assim, para nossos propósitos, o paralelismo pode ser pensado como um caso especial de concorrência
Fonte: Outra resposta aqui
Espero que ajude.
Eu realmente gosto da resposta de Paul Butcher a esta pergunta (ele é o escritor de Sete Modelos de Concorrência em Sete Semanas ):
Embora muitas vezes estejam confusos, paralelismo e simultaneidade são coisas diferentes. A simultaneidade é um aspecto do domínio do problema - seu código precisa manipular vários eventos simultâneos (ou quase simultâneos) . O paralelismo, por outro lado, é um aspecto do domínio da solução - você deseja acelerar o programa processando diferentes partes do problema em paralelo. Algumas abordagens são aplicáveis à simultaneidade, algumas ao paralelismo e outras às duas. Entenda com que você se depara e escolha a ferramenta certa para o trabalho.
A simultaneidade pode envolver tarefas executadas simultaneamente ou não (elas podem realmente ser executadas em processadores / núcleos separados, mas também podem ser executadas em "ticks"). O importante é que a simultaneidade sempre se refira à realização de uma tarefa maior . Então basicamente faz parte de alguns cálculos. Você precisa ser inteligente sobre o que pode fazer simultaneamente e o que não fazer e como sincronizar.
Paralelismo significa que você está fazendo algumas coisas simultaneamente. Eles não precisam fazer parte da solução de um problema. Seus threads podem, por exemplo, resolver um único problema cada. É claro que o material de sincronização também se aplica, mas de uma perspectiva diferente.
"Concorrência" é quando há várias coisas em andamento .
"Paralelismo" é quando coisas simultâneas estão progredindo ao mesmo tempo .
Exemplos de simultaneidade sem paralelismo:
SqlDataReader
s em uma conexão MARS .Observe, no entanto, que a diferença entre simultaneidade e paralelismo é frequentemente uma questão de perspectiva. Os exemplos acima não são paralelos da perspectiva de (efeitos observáveis de) executar seu código. Mas há paralelismo no nível da instrução, mesmo dentro de um único núcleo. Há peças de hardware fazendo coisas em paralelo com a CPU e interrompendo a CPU quando terminar. A GPU pode estar desenhando na tela enquanto o procedimento de janela ou o manipulador de eventos está sendo executado. O DBMS pode estar atravessando árvores B para a próxima consulta enquanto você ainda está buscando os resultados da anterior. O navegador pode estar fazendo o layout ou a rede enquanto o seu Promise.resolve()
está sendo executado. Etc etc...
Então lá vai você. O mundo está tão bagunçado como sempre;)
A maneira mais simples e elegante de entender os dois na minha opinião é essa. A simultaneidade permite a intercalação da execução e, portanto, pode dar a ilusão de paralelismo. Isso significa que um sistema simultâneo pode executar seu vídeo do YouTube ao lado de você escrevendo um documento no Word, por exemplo. O sistema operacional subjacente, sendo um sistema simultâneo, permite que essas tarefas intercalem sua execução. Como os computadores executam instruções tão rapidamente, isso dá a impressão de fazer duas coisas ao mesmo tempo.
Paralelismo é quando essas coisas realmente estão em paralelo. No exemplo acima, você pode achar que o código de processamento de vídeo está sendo executado em um único núcleo e o aplicativo Word está sendo executado em outro. Observe que isso significa que um programa simultâneo também pode estar em paralelo! Estruturar seu aplicativo com threads e processos permite que seu programa explore o hardware subjacente e potencialmente seja feito em paralelo.
Por que não ter tudo paralelo então? Um dos motivos é que a simultaneidade é uma maneira de estruturar programas e é uma decisão de design para facilitar a separação de preocupações, enquanto o paralelismo é frequentemente usado em nome do desempenho. Outra é que algumas coisas fundamentalmente não podem ser totalmente feitas em paralelo. Um exemplo disso seria adicionar duas coisas na parte de trás de uma fila - você não pode inserir as duas ao mesmo tempo. Algo deve passar primeiro e o outro por trás, ou você estraga a fila. Embora possamos intercalar essa execução (e assim obtermos uma fila simultânea), você não pode tê-la em paralelo.
Espero que isto ajude!
A programação simultânea considera operações que parecem se sobrepor e se preocupa principalmente com a complexidade que surge devido ao fluxo de controle não determinístico. Os custos quantitativos associados aos programas simultâneos são geralmente taxa de transferência e latência. Os programas simultâneos geralmente são vinculados à IO, mas nem sempre, por exemplo, coletores de lixo simultâneos são totalmente na CPU. O exemplo pedagógico de um programa simultâneo é um rastreador da web. Este programa inicia solicitações de páginas da web e aceita as respostas simultaneamente à medida que os resultados dos downloads ficam disponíveis, acumulando um conjunto de páginas que já foram visitadas. O fluxo de controle não é determinístico porque as respostas não são necessariamente recebidas na mesma ordem sempre que o programa é executado. Essa característica pode dificultar a depuração de programas concorrentes. Algumas aplicações são fundamentalmente simultâneas, por exemplo, servidores da Web devem lidar com conexões de clientes simultaneamente. Erlang é talvez a linguagem mais promissora para programação altamente concorrente.
A programação paralela refere-se a operações sobrepostas para o objetivo específico de melhorar a taxa de transferência. As dificuldades da programação simultânea são evitadas, tornando o fluxo de controle determinístico. Normalmente, os programas geram conjuntos de tarefas filho que são executadas em paralelo e a tarefa pai continua apenas quando todas as subtarefas são concluídas. Isso torna os programas paralelos muito mais fáceis de depurar. A parte mais difícil da programação paralela é a otimização do desempenho em relação a questões como granularidade e comunicação. O último ainda é um problema no contexto de multicores porque há um custo considerável associado à transferência de dados de um cache para outro. A multiplicação matricial densa de matriz é um exemplo pedagógico de programação paralela e pode ser resolvida com eficiência usando o software Straasen '. s dividir e conquistar algoritmo e atacar os subproblemas em paralelo. Cilk é talvez a linguagem mais promissora para programação paralela de alto desempenho em computadores com memória compartilhada (incluindo multicores).
Copiado da minha resposta: https://stackoverflow.com/a/3982782
Paralelismo: Ter vários encadeamentos executa tarefas semelhantes, independentes entre si em termos de dados e recursos necessários para fazê-lo. Por exemplo: o rastreador do Google pode gerar milhares de threads e cada thread pode fazer sua tarefa de forma independente.
Concorrência: a simultaneidade entra em cena quando você compartilha dados, recursos compartilhados entre os segmentos. Em um sistema transacional, isso significa que você precisa sincronizar a seção crítica do código usando algumas técnicas como bloqueios, semáforos etc.
(Estou bastante surpreso que uma pergunta tão fundamental não seja resolvida corretamente e por anos ...)
Em suma, simultaneidade e paralelismo são propriedades da computação .
Quanto à diferença, aqui está a explicação de Robert Harper :
A primeira coisa a entender é o paralelismo não tem nada a ver com simultaneidade . A simultaneidade preocupa-se com a composição não determinística dos programas (ou seus componentes). O paralelismo está relacionado à eficiência assintótica de programas com comportamento determinístico . A simultaneidade tem tudo a ver com gerenciar o incontrolável: os eventos chegam por razões além do nosso controle, e devemos responder a eles. Um usuário clica em um mouse, o gerenciador de janelas deve responder, mesmo que a tela exija atenção. Tais situações são inerentemente não determinísticas, mas também empregamos pro formanão determinismo em um cenário determinístico, fingindo que os componentes sinalizam eventos em uma ordem arbitrária e que devemos responder a eles à medida que surgem. A composição não determinística é uma poderosa idéia de estruturação de programa. O paralelismo, por outro lado, tem tudo a ver com dependências entre as subcomputações de uma computação determinística. O resultado não está em dúvida, mas existem muitos meios para alcançá-lo, alguns mais eficientes que outros. Desejamos explorar essas oportunidades em nosso proveito.
Eles podem ser tipos de propriedades ortogonais em programas. Leia esta postagem do blog para obter ilustrações adicionais. E este discutiu um pouco mais sobre a diferença sobre componentes na programação , como threads.
Observe que threading ou multitarefa são todas implementações da computação que servem a propósitos mais concretos. Eles podem estar relacionados ao paralelismo e simultaneidade, mas não de uma maneira essencial. Portanto, dificilmente são boas entradas para começar a explicação.
Mais um destaque: o "tempo" (físico) não tem quase nada a ver com as propriedades discutidas aqui. O tempo é apenas uma maneira de implementar a medida para mostrar o significado das propriedades, mas longe da essência. Pense duas vezes no papel do "tempo" na complexidade do tempo - que é mais ou menos semelhante; até mesmo a medição é mais significativa nesse caso.
"Concorrente" está fazendo coisas - qualquer coisa - ao mesmo tempo. Eles podem ser coisas diferentes, ou a mesma coisa. Apesar da resposta aceita, que está faltando, não se trata de "parecer estar ao mesmo tempo". É realmente ao mesmo tempo. Você precisa de vários núcleos de CPU, usando memória compartilhada em um host ou memória distribuída em hosts diferentes, para executar o código simultâneo. Os pipelines de 3 tarefas distintas que são executadas simultaneamente ao mesmo tempo são um exemplo: o nível de tarefa 2 precisa aguardar unidades concluídas pelo nível de tarefa 1 e o nível 3 de tarefa precisa aguardar as unidades de trabalho concluídas por tarefa-nível-2. Outro exemplo é a simultaneidade de 1 produtor com 1 consumidor; ou muitos produtores e 1 consumidor; leitores e escritores; et al.
"Paralelo" está fazendo as mesmas coisas ao mesmo tempo. É simultâneo, mas, além disso, é o mesmo comportamento acontecendo ao mesmo tempo e, geralmente, em dados diferentes. A álgebra da matriz geralmente pode ser paralelizada, porque você tem a mesma operação executando repetidamente: Por exemplo, as somas de colunas de uma matriz podem ser calculadas ao mesmo tempo usando o mesmo comportamento (soma), mas em colunas diferentes. É uma estratégia comum particionar (dividir) as colunas entre os núcleos de processador disponíveis, para que você tenha quase a mesma quantidade de trabalho (número de colunas) sendo tratado por cada núcleo de processador. Outra maneira de dividir o trabalho é o conjunto de tarefas em que os trabalhadores que terminam o trabalho retornam a um gerente que distribui o trabalho e trabalha mais dinamicamente até que tudo esteja pronto. O algoritmo de emissão de bilhetes é outro.
Não apenas o código numérico pode ser paralelo. Arquivos com muita freqüência podem ser processados em paralelo. Em um aplicativo de processamento de idioma natural, para cada um dos milhões de arquivos de documento, pode ser necessário contar o número de tokens no documento. Isso é paralelo, porque você está contando tokens, que é o mesmo comportamento, para cada arquivo.
Em outras palavras, paralelismo é quando o mesmo comportamento está sendo executado simultaneamente. Simultaneamente, significa ao mesmo tempo, mas não necessariamente o mesmo comportamento. Paralelo é um tipo específico de simultaneidade em que a mesma coisa está acontecendo ao mesmo tempo.
Os termos, por exemplo, incluem instruções atômicas, seções críticas, exclusão mútua, espera em rotação, semáforos, monitores, barreiras, passagem de mensagem, mapa de redução, batimento cardíaco, anel, algoritmos de emissão de bilhetes, threads, MPI, OpenMP.
O trabalho de Gregory Andrews é um livro de referência: Programação Multithread, Paralela e Distribuída.
Ótimo, deixe-me ver um cenário para mostrar o que entendo. suponha que haja três crianças nomeadas: A, B, C. A e B conversam, C ouve. Para A e B, eles são paralelos: A: Eu sou A. B: Eu sou B.
Mas, para C, seu cérebro deve seguir o processo simultâneo para ouvir A e B, talvez: eu sou IA, sou B.
Simultaneidade simples significa que mais de uma tarefa está em execução (não é necessária em paralelo). Por exemplo, assumidor, temos três tarefas e a qualquer momento: mais de uma pode estar em execução ou todas podem estar em execução ao mesmo tempo.
Paralelismo significa que eles estão literalmente funcionando paralelamente. Portanto, nesse caso, os três devem estar em execução ao mesmo tempo.
A noção de "simultaneidade" de Pike é uma decisão intencional de projeto e implementação. Um design de programa com capacidade simultânea pode ou não exibir "paralelismo" comportamental; isso depende do ambiente de tempo de execução.
Você não deseja que o paralelismo seja exibido por um programa que não foi projetado para simultaneidade. :-) Mas, na medida em que é um ganho líquido para os fatores relevantes (consumo de energia, desempenho etc.), você deseja um design simultâneo máximo para que o sistema host possa paralelizar sua execução sempre que possível.
A linguagem de programação Go de Pike ilustra isso ao extremo: suas funções são todas as threads que podem funcionar corretamente simultaneamente, ou seja, chamar uma função sempre cria uma thread que será executada em paralelo com o chamador, se o sistema for capaz disso. Uma aplicação com centenas ou mesmo milhares de threads é perfeitamente comum em seu mundo. (Eu não sou especialista em Go, essa é apenas a minha opinião.)