Qual é a diferença entre programação simultânea e programação paralela?

346

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ê.

matekm
fonte

Respostas:

310

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.

Tor Valamo
fonte
34
Execução paralela e programação paralela não são a mesma coisa. A resposta de Jon Harrop está correta. Mas parece que a pergunta em si confunde execução paralela e programação paralela.
Blaisorblade
3
A capacidade de executar threads em paralelo depende mais do que apenas a máquina. Por exemplo, OCaml (e Python?) Executa threads simultaneamente, mas não em paralelo devido a um bloqueio global para o coletor de lixo.
quer
11
A programação paralela não é um subconjunto da programação simultânea, de acordo com este blog ; sua resposta não leva isso em consideração, o que você acha dessa afirmação?
Kevin
11
@ Kevin: Eu acho que "mais geral" significa superconjunto. Eu concordo que está errado.
9133 Jon Harrop
11
Essa resposta é boa para visualizar a diferença entre execução simultânea e paralela, mas não para a pergunta original do autor sobre programação .
Reorx
396

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).

Jon Harrop
fonte
18
"A parte difícil da programação paralela ... como granularidade e comunicação." Se tarefas paralelas precisam se comunicar, isso não as torna concorrentes?
Justin M. Keyes
13
"Se tarefas paralelas precisam se comunicar, isso não as torna concorrentes?". Uau, ótima pergunta! Não necessariamente não. Os supercomputadores geralmente são programados com operações paralelas em massa seguidas de redistribuição global de dados e mais paralelismo em massa. Portanto, há paralelismo e comunicação, mas não há concorrência real para se falar. Nesse contexto, eu estava pensando mais em paralelismo multicore, em que comunicação significa complexidade do cache, por exemplo, comunicação necessária para a coerência do cache. Embora isso seja simultâneo, também não é diretamente visível.
quer
43
@BoppityBop Só porque posso dizer em um desenho o que ele disse em um romance não torna minha resposta menos correta. Apenas mais fácil de ler para quem realmente não sabe a resposta. O que eu acho que é o ponto de vir aqui. Você pode escrever um livro no idioma usado neste post, mas isso será absolutamente ridículo para a maioria dos leitores, pois você provavelmente não pesquisou essa pergunta no Google se já conhece metade do que Jon escreveu.
Tor Valamo 04/04
18
A imagem foi muito útil para mim, alguém bastante novo para o tópico, e a descrição de @JonHarrop foi útil para mim, alguém que aprecia a linguagem correta, mesmo que técnica. Ambas as respostas contribuíram para minha compreensão mais completa. Todos nós ganhamos! (apesar de eu apreciar a distinção entre execução paralela e programação paralela)
Sammaron
3
"Erlang é talvez o próximo idioma mais promissor ...". Interessante escolha de palavras, já que Erlang é ~ 30 anos de idade e foi código aberto em 1998.
Steinar
151

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é.

Grigory Kislin
fonte
9
Incorreto e enganoso. Concorrente = permite uma ou mais filas (composição não determinística). Paralela = ter mais de uma fila para tornar uma delas mais curta que a original, se não estiver vazia (eficiência assintótica).
FrankHB 02/02
O código simultâneo requer dois ou mais processadores (ou "máquinas de café"). Portanto, essa resposta está essencialmente errada.
Geoffrey Anderson
6
@GeoffreyAnderson Não, não. Por exemplo, threads e processos são executados simultaneamente em uma máquina de núcleo único.
Jon Harrop
@FrankHB - Dê uma olhada em stackoverflow.com/a/57223044/1406510 e verifique o link de origem - no site da Oracle - Portanto, não pode estar errado, mas nosso entendimento pode estar. Então, hora de repensar. Eu mudei de opinião depois de ler isso.
Nanosoft 26/07/19
@GeoffreyAnderson - Dê uma olhada em stackoverflow.com/a/57223044/1406510. Ele contém um link do oracle e indica claramente o que é o quê. Então, precisamos nos alinhar com isso.
Nanosoft 26/07/19
40

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"

suspensão e revezamento versus computação paralela

pspi
fonte
21

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.

Manuel Selva
fonte
2
Em outras palavras, executar duas coisas em paralelo pode fazê-las duas vezes mais rápido. A execução simultânea de duas coisas ainda pode levar a mesma quantidade de tempo que a primeira e depois a outra, se houver apenas uma CPU que corta o tempo entre a execução de uma parte da primeira e depois da segunda, etc.
user189169
14

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

loknath
fonte
9

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.

Jerry Coffin
fonte
6
  • Concurrent programmingé geralmente referir-se a ambientes nos quais as tarefas que definimos podem ocorrer em qualquer ordem. Uma tarefa pode ocorrer antes ou depois da outra e algumas ou todas as tarefas podem ser executadas ao mesmo tempo.

  • Parallel programmingé se referir especificamente à execução simultânea de tarefas simultâneas em diferentes processadores. Assim, toda a programação paralela é simultânea, mas nem toda a programação simultânea é paralela.

Fonte: PThreads Programming - Um padrão POSIX para melhor multiprocessamento, Buttlar, Farrell, Nichols

snr
fonte
5

Na programação, simultaneidade é a composição de processos de execução independente, enquanto paralelismo é a execução simultânea de cálculos (possivelmente relacionados).
- Andrew Gerrand -

E

Simultaneidade é a composição de cálculos de execução independente. A simultaneidade é uma maneira de estruturar o software, particularmente como forma de escrever código limpo que interage bem com o mundo real. Não é paralelismo.

A simultaneidade não é paralelismo, embora permita paralelismo. Se você tiver apenas um processador, seu programa ainda poderá ser simultâneo, mas não poderá ser paralelo. Por outro lado, um programa simultâneo bem escrito pode ser executado de forma eficiente em paralelo em um multiprocessador. Essa propriedade pode ser importante ...
- Rob Pike -

Para entender a diferença, recomendo fortemente ver o vídeo de Rob Pike (um dos criadores de Golang). A simultaneidade não é paralelismo

Jinbom Heo
fonte
O link vimeo não está funcionando aqui é o link do youtube youtube.com/watch?v=cN_DpYBzKso
Shivprasad Koirala
5

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.

sharp_c-tudent
fonte
5

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.

    • Qualquer falha de qualquer uma das tarefas - funcionalmente ou a tempo - resultará em falha total do sistema.
    • Todas as tarefas devem ter um senso de tempo confiável e comum.

    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:

  • o verbo - o que você está fazendo (operação ou algoritmo)
  • o substantivo - o que você está fazendo (dados ou interface)
  • when - iniciação, programação, mudanças de estado
  • how - serial, paralelo, simultâneo
  • onde - quando você souber quando as coisas acontecem, pode dizer onde elas podem acontecer e não antes.
  • por que - é assim que se faz? Existem outras maneiras, e mais importante, uma maneira melhor ? O que acontece se você não fizer isso?

Boa sorte.

Don
fonte
8
Eu vejo bonés em todos os lugares
Bruno Penteado
10
Essa resposta é mais complicada do que os tópicos de simultaneidade e paralelismo juntos.
Kai Sellgren
3

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).

Jonathan
fonte
3

Embora não haja acordo completo sobre a distinção entre os termos paralelo e concorrente , muitos autores fazem as seguintes distinções:

  • Na computação simultânea, um programa é aquele em que várias tarefas podem estar em andamento a qualquer momento.
  • Na computação paralela, um programa é aquele em que várias tarefas cooperam estreitamente para resolver um problema.

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

zbs
fonte
1

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.

nanosoft
fonte
Essa fonte mostra apenas um caso especial da implementação - uma forma especializada de multithreading. Sim, ele nem cobre toda a história do multithreading, por exemplo, o modelo de threading M: N do espaço do usuário e o papel do agendamento de threads. A segmentação é apenas uma maneira especializada de implementação no sentido da arquitetura do sistema (SO, VM, CPU com HT habilitado, etc) e / ou a interface de programação. Existem mais, como o paralelismo em nível de instrução na implementação de uma CPU moderna que não expõe nenhuma interface de programação e não tem nada a ver com threads.
FrankHB 26/07/19
@FrankHB: Eu gostaria que você pudesse compartilhar links autênticos sobre o seu conteúdo. Eu realmente gostaria de explorar se há mais. Meu entendimento atual é bastante simplista - a execução de um aplicativo multithread em qualquer arquitetura de SO com determinado mecanismo de agendamento de threads é paralela ou simultânea, é a questão? Mesmo se você fornecer o espaço de usuário M: N - Como você percebe que o RUN é paralelo ou simultâneo?
Nanosoft 31/07/19
Eu escrevi uma resposta para discutir os problemas em diferentes abstrações.
FrankHB 01/08/19
A execução de um aplicativo multithread é realmente bastante complexa em comparação com a abstração básica, pois "run" é uma ação geral adequada para muitas abstrações. Há muitos detalhes que devem ter sido complementados pelo modelo de encadeamento na implementação (normalmente, a especificação de linguagem e a implementação de runtime de linguagem usada para programar o aplicativo) na abstração básica.
FrankHB 01/08/19
0

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.

FrankHB
fonte
0

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.

A. Mashreghi
fonte
0

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,

A --> cleaning dishes
B --> taking out trash 
C --> mowing the lawn 

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:

A --> soaping the dishes
B --> washing the dishes

em breve

Espero que isso dê uma idéia! Agora, vá para os termos técnicos explicados nas outras respostas;)

Jagadeesh Venkata
fonte