Qual é a diferença entre programação simultânea e programação paralela? Perguntei ao google, mas não encontrei nada que me ajudasse a entender essa diferença. Você poderia me dar um exemplo para ambos?
Por enquanto, encontrei esta explicação: http://www.linux-mag.com/id/7411 - mas "simultaneidade é uma propriedade do programa" vs "a execução paralela é uma propriedade da máquina" não é suficiente para mim - ainda não sei dizer o que é o quê.
Respostas:
Se você programar usando threads (programação simultânea), não será necessariamente executado como tal (execução paralela), pois depende se a máquina pode lidar com vários threads.
Aqui está um exemplo visual. Threads em uma máquina não-threaded :
Roscas em uma máquina rosqueada :
Os traços representam o código executado. Como você pode ver, eles se dividem e executam separadamente, mas a máquina rosqueada pode executar várias peças separadas ao mesmo tempo.
fonte
Programação concorrentediz respeito às 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. Esse 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.Erlang , fluxos de trabalho assíncronos em F # e a biblioteca Akka da Scala são talvez as abordagens mais promissoras para programação altamente simultânea.
Programação multicoreé um caso especial de programação paralela. 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 do que os programas concorrentes. 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 vários núcleos, porque há um custo considerável associado à transferência de dados de um cache para outro.Cilk é talvez a abordagem mais promissora para a programação paralela de alto desempenho em multicores e foi adotada nos Threaded Building Blocks da Intel e na Task Parallel Library da Microsoft (no .NET 4).
fonte
https://joearms.github.io/published/2013-04-05-concurrent-and-parallel-programming.html
Simultâneo = Duas filas e uma máquina de café.
Paralelo = Duas filas e duas máquinas de café.
fonte
Interpretar a pergunta original como computação paralela / simultânea, em vez de programação .
Na computação simultânea, duas computações avançam independentemente uma da outra. O segundo cálculo não precisa esperar até que o primeiro termine para avançar. Não indica, no entanto, o mecanismo de como isso é alcançado. Na configuração de núcleo único, é necessário suspender e alternar entre threads (também chamado de multithreading preventivo ).
Em computação paralela, duas computações avançam simultaneamente - isso é literalmente ao mesmo tempo. Isso não é possível com uma única CPU e requer a configuração de vários núcleos.
Imagens do artigo: "Paralelo vs Concorrente no Node.js"
versus
fonte
Na visão de um processador, pode ser descrito por esta foto
Na visão de um processador, pode ser descrito por esta foto
fonte
Acredito que a programação simultânea se refere à programação multithread, que consiste em deixar o programa executar vários threads, abstraídos dos detalhes do hardware.
A programação paralela refere-se ao design específico dos algoritmos do seu programa para aproveitar a execução paralela disponível. Por exemplo, você pode executar em paralelo duas ramificações de alguns algoritmos, na expectativa de que o resultado seja atingido mais cedo (em média) do que seria se você primeiro verificasse a primeira e depois a segunda ramificação.
fonte
Encontrei esse conteúdo em algum blog. Pensei que fosse útil e relevante.
Concorrência e paralelismo NÃO são a mesma coisa. Duas tarefas T1 e T2 são simultâneas se a ordem na qual as duas tarefas são executadas no tempo não for predeterminada,
T1 pode ser executado e finalizado antes de T2, T2 pode ser executado e finalizado antes de T1, T1 e T2 podem ser executados simultaneamente na mesma instância de tempo (paralelismo), T1 e T2 podem ser executados alternativamente, ... Se dois threads simultâneos Se o SO estiver agendado para ser executado em um processador não-SMT não-CMP de núcleo único, você poderá obter simultaneidade, mas não paralelismo. O paralelismo é possível em sistemas com vários núcleos, multiprocessadores ou distribuídos.
A simultaneidade é frequentemente referida como propriedade de um programa e é um conceito mais geral que paralelismo.
Fonte: https://blogs.oracle.com/yuanlin/entry/concurrency_vs_parallelism_concurrent_programming
fonte
São duas frases que descrevem a mesma coisa de pontos de vista diferentes (muito pouco). A programação paralela está descrevendo a situação do ponto de vista do hardware - há pelo menos dois processadores (possivelmente dentro de um único pacote físico) trabalhando em um problema em paralelo. A programação simultânea está descrevendo as coisas mais do ponto de vista do software - duas ou mais ações podem acontecer exatamente ao mesmo tempo (simultaneamente).
O problema aqui é que as pessoas estão tentando usar as duas frases para fazer uma distinção clara quando realmente não existe. A realidade é que a linha divisória que eles estão tentando traçar é nebulosa e indistinta há décadas e se torna cada vez mais indistinta ao longo do tempo.
O que eles estão tentando discutir é o fato de que, uma vez, a maioria dos computadores tinha apenas uma única CPU. Quando você executava vários processos (ou threads) naquela CPU única, a CPU estava realmente executando apenas uma instrução de um desses threads por vez. A aparência de simultaneidade era uma ilusão - a CPU alternava entre executar instruções de diferentes threads com rapidez suficiente para que, para a percepção humana (para a qual algo menos de 100 ms parecesse instantâneo), parecia que ele estava fazendo muitas coisas ao mesmo tempo.
O contraste óbvio para isso é um computador com várias CPUs, ou uma CPU com vários núcleos; portanto, a máquina está executando instruções de vários threads e / ou processos exatamente ao mesmo tempo; código executando um não pode / não tem efeito sobre o código executado no outro.
Agora o problema: uma distinção tão limpa quase nunca existiu. Os projetistas de computadores são realmente bastante inteligentes; portanto, eles perceberam há muito tempo que (por exemplo) quando você precisava ler alguns dados de um dispositivo de E / S, como um disco, levava muito tempo (em termos de ciclos da CPU) para terminar. Em vez de deixar a CPU inativa enquanto isso acontecia, eles descobriram várias maneiras de permitir que um processo / encadeamento faça uma solicitação de E / S e permita que o código de outro processo / encadeamento seja executado na CPU enquanto a solicitação de E / S é concluída.
Portanto, muito antes de as CPUs multinúcleo se tornarem a norma, tínhamos operações de vários threads acontecendo paralelamente.
Essa é apenas a ponta do iceberg. Décadas atrás, os computadores começaram a fornecer outro nível de paralelismo também. Novamente, por serem pessoas bastante inteligentes, os projetistas de computadores perceberam que, em muitos casos, eles tinham instruções que não se afetavam, por isso era possível executar mais de uma instrução no mesmo fluxo ao mesmo tempo. Um exemplo inicial que ficou bem conhecido foi o Control Data 6600. Esse (por uma margem bastante ampla) foi o computador mais rápido do mundo quando foi lançado em 1964 - e grande parte da mesma arquitetura básica permanece em uso atualmente. Ele rastreava os recursos utilizados por cada instrução e possuía um conjunto de unidades de execução que executavam instruções assim que os recursos dos quais dependiam eram disponibilizados, muito semelhante ao design dos processadores Intel / AMD mais recentes.
Mas (como costumavam dizer os comerciais) espera - isso não é tudo. Há ainda outro elemento de design para adicionar ainda mais confusão. Receberam vários nomes diferentes (por exemplo, "Hyperthreading", "SMT", "CMP"), mas todos se referem à mesma idéia básica: uma CPU que pode executar vários threads simultaneamente, usando uma combinação de alguns recursos que são independentes para cada encadeamento e alguns recursos que são compartilhados entre os encadeamentos. Em um caso típico, isso é combinado com o paralelismo em nível de instrução descrito acima. Para fazer isso, temos dois (ou mais) conjuntos de registros arquitetônicos. Em seguida, temos um conjunto de unidades de execução que podem executar instruções assim que os recursos necessários estiverem disponíveis.
Então, é claro, chegamos a sistemas modernos com múltiplos núcleos. Aqui as coisas são óbvias, certo? Temos N (algo entre 2 e 256, no momento) núcleos separados, que podem executar instruções ao mesmo tempo; portanto, temos um caso claro de paralelismo real - executar instruções em um processo / thread não ' afeta a execução de instruções em outro.
Bem, mais ou menos. Mesmo aqui, temos alguns recursos independentes (registros, unidades de execução, pelo menos um nível de cache) e alguns recursos compartilhados (geralmente pelo menos o nível mais baixo de cache, e definitivamente os controladores de memória e a largura de banda na memória).
Resumindo: os cenários simples que as pessoas gostam de contrastar entre recursos compartilhados e recursos independentes praticamente nunca acontecem na vida real. Com todos os recursos compartilhados, acabamos com algo como o MS-DOS, onde só podemos executar um programa por vez e precisamos parar de executar um antes que possamos executar o outro. Com recursos completamente independentes, temos N computadores executando o MS-DOS (sem sequer uma rede para conectá-los) sem capacidade de compartilhar nada entre eles (porque, se é que podemos compartilhar um arquivo, bem, isso é um recurso compartilhado, um violação da premissa básica de que nada está sendo compartilhado).
Todo caso interessante envolve alguma combinação de recursos independentes e recursos compartilhados. Todo computador razoavelmente moderno (e muitos que não são nada modernos) tem pelo menos alguma capacidade de executar pelo menos algumas operações independentes simultaneamente e praticamente qualquer coisa mais sofisticada do que o MS-DOS aproveitou isso para pelo menos algum grau.
A divisão agradável e limpa entre "simultâneo" e "paralelo" que as pessoas gostam de desenhar simplesmente não existe, e quase nunca existe. O que as pessoas gostam de classificar como "simultâneo" geralmente ainda envolve pelo menos um e muitas vezes mais tipos diferentes de execução paralela. O que eles gostam de classificar como "paralelo" geralmente envolve o compartilhamento de recursos e (por exemplo) um processo que bloqueia a execução de outro enquanto usa um recurso compartilhado entre os dois.
As pessoas que tentam fazer uma distinção clara entre "paralelo" e "concorrente" estão vivendo uma fantasia de computadores que nunca existiram.
fonte
Fonte: PThreads Programming - Um padrão POSIX para melhor multiprocessamento, Buttlar, Farrell, Nichols
fonte
E
Para entender a diferença, recomendo fortemente ver o vídeo de Rob Pike (um dos criadores de Golang). A simultaneidade não é paralelismo
fonte
A programação paralela acontece quando o código está sendo executado ao mesmo tempo e cada execução é independente da outra. Portanto, geralmente não há uma preocupação com variáveis compartilhadas e tal, porque isso provavelmente não acontecerá.
No entanto, a programação simultânea consiste no código sendo executado por diferentes processos / threads que compartilham variáveis e tal; portanto, na programação simultânea, devemos estabelecer algum tipo de regra para decidir qual processo / thread será executado primeiro, queremos isso para que possamos ter certeza de que haverá consistência e que possamos saber com certeza o que acontecerá. Se não houver controle e todos os threads computarem ao mesmo tempo e armazenar coisas nas mesmas variáveis, como saberemos o que esperar no final? Talvez um encadeamento seja mais rápido que o outro, talvez um dos encadeamentos tenha parado no meio de sua execução e outro tenha continuado um cálculo diferente com uma variável corrompida (ainda não totalmente calculada), as possibilidades são infinitas. É nessas situações que geralmente usamos programação simultânea em vez de paralela.
fonte
O agendamento clássico de tarefas pode ser serial , paralelo ou simultâneo .
Serial : as tarefas devem ser executadas uma após a outra em uma ordem de truque conhecida ou não funcionará. Bastante fácil.
Paralelo : as tarefas devem ser executadas ao mesmo tempo ou não funcionarão.
Tente evitar isso ou teremos lágrimas na hora do chá.
Simultaneamente : nós não nos importamos. Não somos descuidados: analisamos e isso não importa; portanto, podemos executar qualquer tarefa usando qualquer recurso disponível a qualquer momento. Dias felizes.
Freqüentemente, o agendamento disponível muda em eventos conhecidos que chamamos de mudança de estado.
As pessoas geralmente pensam que se trata de software, mas, na verdade, é um conceito de design de sistemas que antecede os computadores; os sistemas de software foram um pouco lentos na adoção, muito poucas linguagens de software tentam resolver o problema. Você pode tentar procurar o idioma do computador se você estiver interessado.
Sucintamente, o design de sistemas aborda o seguinte:
Boa sorte.
fonte
Eu entendi a diferença:
1) Concorrente - executando em conjunto usando recursos compartilhados 2) Paralelo - executando lado a lado usando recursos diferentes
Portanto, você pode ter duas coisas acontecendo ao mesmo tempo, independentes uma da outra, mesmo que elas se reúnam nos pontos (2) ou duas coisas se baseando nas mesmas reservas durante as operações executadas (1).
fonte
Embora não haja acordo completo sobre a distinção entre os termos paralelo e concorrente , muitos autores fazem as seguintes distinções:
Portanto, programas paralelos são simultâneos, mas um programa como um sistema operacional multitarefa também é simultâneo, mesmo quando executado em uma máquina com apenas um núcleo, pois várias tarefas podem estar em andamento a qualquer momento.
Fonte : Uma introdução à programação paralela, Peter Pacheco
fonte
Concorrência e paralelismo Fonte de
Em um processo multithread em um único processador, o processador pode alternar recursos de execução entre threads, resultando em execução simultânea .
No mesmo processo multithread em um ambiente de multiprocessador de memória compartilhada, cada thread no processo pode ser executado em um processador separado ao mesmo tempo, resultando em execução paralela .
Quando o processo possui menos ou tantos threads quanto processadores, os threads suportam o sistema em conjunto com o ambiente operacional, garantindo que cada thread seja executado em um processador diferente.
Por exemplo, em uma multiplicação de matrizes que possui o mesmo número de threads e processadores, cada thread (e cada processador) calcula uma linha do resultado.
fonte
Pessoas diferentes falam sobre diferentes tipos de simultaneidade e paralelismo em muitos casos específicos diferentes; portanto, são necessárias algumas abstrações para cobrir sua natureza comum.
A abstração básica é feita em ciência da computação, onde simultaneidade e paralelismo são atribuídos às propriedades dos programas . Aqui, os programas são descrições formalizadas da computação. Esses programas não precisam estar em nenhuma linguagem ou codificação específica, específica da implementação. A existência de API / ABI / ISA / OS é irrelevante para esse nível de abstração. Certamente será necessário um conhecimento mais específico da implementação (como o modelo de encadeamento) para realizar trabalhos de programação concretos, o espírito por trás da abstração básica não é alterado.
Um segundo fato importante é que, como propriedades gerais, simultaneidade e paralelismo podem coexistir em muitas abstrações diferentes .
Para a distinção geral, consulte a resposta relevante para a visão básica de concorrência versus paralelismo. (Também existem alguns links que contêm algumas fontes adicionais.)
Programação simultânea e programação paralela são técnicas para implementar essas propriedades gerais em alguns sistemas que expõem a capacidade de programação. Os sistemas geralmente são linguagens de programação e suas implementações.
Uma linguagem de programação pode expor as propriedades pretendidas por regras semânticas internas. Na maioria dos casos, essas regras especificam as avaliações de estruturas de linguagem específicas (por exemplo, expressões), tornando a computação envolvida efetivamente simultânea ou paralela. (Mais especificamente, os efeitos computacionais implícitos nas avaliações podem refletir perfeitamente essas propriedades.) No entanto, a semântica da linguagem simultânea / paralela é essencialmente complexa e não é necessária para trabalhos práticos (para implementar algoritmos simultâneos / paralelos eficientes como soluções de problemas realistas). ) Portanto, a maioria das linguagens tradicionais adota uma abordagem mais conservadora e mais simples: assumindo que a semântica da avaliação seja totalmente seqüencial e serial, fornecendo primitivas opcionais para permitir algumasdos cálculos sendo simultâneos e paralelos. Essas primitivas podem ser palavras-chave ou construções processuais ("funções") suportadas pelo idioma. Eles são implementados com base na interação com ambientes hospedados (SO ou interface de hardware "bare metal"), geralmente opacos (não capazes de derivar usando o idioma de forma portável) para o idioma. Assim, nesse tipo específico de abstração de alto nível visto pelos programadores, nada é simultâneo / paralelo além dessas primitivas e programas "mágicos" que dependem dessas primitivas; os programadores podem desfrutar de uma experiência menos propensa a erros de programação quando as propriedades de simultaneidade / paralelismo não estiverem tão interessadas.
Embora as primitivas abstraiam o complexo nas abstrações de mais alto nível, as implementações ainda têm uma complexidade extra não exposta pelo recurso de linguagem. Portanto, são necessárias algumas abstrações de nível intermediário. Um exemplo típico é o encadeamento . O encadeamento permite um ou mais encadeamentos de execução (ou simplesmente encadeamento ; às vezes também é chamado de processo , que não é necessariamente o conceito de tarefa agendada em um sistema operacional) suportado pela implementação do idioma (o tempo de execução). Os encadeamentos geralmente são agendados preventivamente pelo tempo de execução, portanto, um encadeamento não precisa saber nada sobre outros encadeamentos. Assim, os threads são naturais para implementar o paralelismo, desde que eles não compartilhem nada (o recursos críticos): apenas decomponha os cálculos em diferentes threads, uma vez que a implementação subjacente permite a sobreposição dos recursos de computação durante a execução, ela funciona. Os encadeamentos também estão sujeitos a acessos simultâneos de recursos compartilhados: basta acessar recursos em qualquer ordem que atenda às restrições mínimas exigidas pelo algoritmo, e a implementação acabará por determinar quando acessar. Nesses casos, algumas operações de sincronização podem ser necessárias. Alguns idiomas tratam as operações de encadeamento e sincronização como partes da abstração de alto nível e as expõem como primitivas, enquanto outras línguas incentivam apenas relativamente mais primitivas de alto nível (como futuros / promessas ).
Sob o nível de threads específicos do idioma, existem multitarefas do ambiente de hospedagem subjacente (normalmente, um sistema operacional). A multitarefa preemptiva no nível do sistema operacional é usada para implementar multithreading (preemptivo). Em alguns ambientes como o Windows NT, as unidades básicas de agendamento (as tarefas) também são "threads". Para diferenciá-los da implementação de threads do espaço do usuário mencionada acima, eles são chamados de threads do kernel, onde "kernel" significa o kernel do sistema operacional (no entanto, estritamente, isso não é verdade no Windows NT; o kernel "real" é o NT executivo) . Os encadeamentos do kernel nem sempre são mapeados 1: 1 para os encadeamentos do espaço do usuário, embora o mapeamento 1: 1 geralmente reduza a maior sobrecarga do mapeamento. Como os threads do kernel são pesados (envolvendo chamadas do sistema) para criar / destruir / comunicar,threads verdes no espaço do usuário para superar os problemas de sobrecarga ao custo da sobrecarga de mapeamento. A escolha do mapeamento, dependendo do paradigma de programação esperado na abstração de alto nível. Por exemplo, quando um grande número de threads do espaço do usuário esperado para execução simultânea (como Erlang), o mapeamento 1: 1 nunca é viável.
A base da multitarefa do SO é a multitarefa no nível ISA, fornecida pelo núcleo lógico do processador. Essa é geralmente a interface pública de mais baixo nível para programadores. Abaixo deste nível, pode existir SMT . Essa é uma forma de multithreading de mais baixo nível implementada pelo hardware, mas sem dúvida ainda é um pouco programável - embora geralmente seja acessível apenas pelo fabricante do processador. Observe que o design do hardware aparentemente reflete o paralelismo, mas também existe um mecanismo de agendamento simultâneo para fazer com que os recursos internos do hardware sejam usados com eficiência.
Em cada nível de "encadeamento" mencionado acima, simultaneidade e paralelismo estão envolvidos. Embora as interfaces de programação variem dramaticamente, todas elas estão sujeitas às propriedades reveladas pela abstração básica no início.
fonte
Apenas compartilhando um exemplo que ajuda a destacar a distinção:
Programação paralela: diga que deseja implementar o algoritmo de classificação por mesclagem . Cada vez que você divide o problema em dois subproblemas, você pode ter dois threads para resolvê-los. No entanto, para executar a etapa de mesclagem, é necessário aguardar a conclusão desses dois encadeamentos, pois a mesclagem requer as duas sub-soluções. Essa "espera obrigatória" faz deste um programa paralelo.
Programa Concorrente: digamos que você deseja compactar n arquivos de texto e gerar um arquivo compactado para cada um deles. Você pode ter de 2 (até n) threads que cada um manipula a compactação de um subconjunto dos arquivos. Quando cada thread está pronto, está pronto, não precisa esperar ou fazer mais nada. Portanto, como diferentes tarefas são executadas de maneira intercalada em "qualquer ordem arbitrária", o programa é simultâneo, mas não paralelo.
Como alguém mencionou, todo programa paralelo é simultâneo (tem que ser de fato), mas não o contrário.
fonte
Vou tentar explicar no meu próprio estilo, pode não ser em termos de computador, mas dá a você uma idéia geral.
Vamos dar um exemplo, digamos, tarefas domésticas: limpar pratos, retirar o lixo, cortar a grama etc., também temos 3 pessoas (linhas) A, B, C para fazê-las
Concorrente: Os três indivíduos iniciam tarefas diferentes independentemente, ou seja,
Aqui, a ordem das tarefas é indeterminista e as respostas dependem da quantidade de trabalho
Paralelo: aqui, se quisermos melhorar a taxa de transferência, podemos atribuir várias pessoas à tarefa única; por exemplo, para limpar a louça, designamos duas pessoas, A ensaboando a louça e B lavando a louça, o que pode melhorar a taxa de transferência.
limpando a louça:
em breve
Espero que isso dê uma idéia! Agora, vá para os termos técnicos explicados nas outras respostas;)
fonte