Aqui eu explico com alguns exemplos
Paralelismo
Uma GPU usa processamento paralelo para processar o mesmo bloco de código ( kernel AKA ) em milhares de encadeamentos físicos e lógicos. Idealmente, o processo inicia e termina para todos os threads ao mesmo tempo. Um único núcleo de CPU sem hyperthreading não pode executar processamento paralelo.
Nota: Eu disse idealmente, porque quando você executa um kernel com tamanho de 7M em um hardware com threads de 6M, ele precisa executar duas vezes executando o mesmo código em todos os threads de 6M em paralelo enquanto consome todos os threads de 6M de cada vez.
- um kernel (um pedaço de código) é executado em vários processadores
- simultaneamente
- com uma única sequência de execução (um kernel deve fazer a mesma coisa em todos os threads, portanto, "ramificação" ou "se" são evitados porque eles consumirão os recursos drasticamente, criando muitos NOPs (sem operações) para sincronizar todos os threads)
- essencialmente aumenta a velocidade drasticamente
- limita drasticamente o que você pode fazer
- depende muito do hardware
Nota: O paralelismo não se limita à GPU.
Concorrência
Um serviço da Web recebe muitas solicitações pequenas em tempo real e precisa lidar com cada uma dessas solicitações de maneira diferente, a qualquer momento e independente de outras solicitações ou trabalhos internos. No entanto, você deseja que o serviço da Web esteja sempre funcionando sem danificar o estado dos dados ou a integridade do sistema.
Imagine um usuário atualizando um registro e outro excluindo o mesmo registro ao mesmo tempo.
- muitas tarefas são executadas
- em tempo real (ou sempre que houver uma solicitação)
- com sequências de execução diferentes (ao contrário do kernel no processamento paralelo, tarefas simultâneas podem fazer coisas diferentes, é provável que você precise enfileirá-las ou priorizá-las)
- essencialmente melhora o tempo médio de resposta porque a tarefa 2 não precisa esperar a tarefa 1 terminar
- essencialmente sacrifica o tempo computacional porque muitas tarefas estão sendo executadas ao mesmo tempo e há recursos limitados
- precisa gerenciar adequadamente os recursos compartilhados para que não ocorra conflitos ou corrompa os dados.
Nota : Essas solicitações geralmente consomem alguns recursos essenciais, como memória, conexão com o banco de dados ou largura de banda. No entanto, você deseja que o serviço da Web seja responsivo o tempo todo. Assíncrona é a chave para torná-lo responsivo , não simultâneo
Assíncrono
Um processo pesado (como uma operação de E / S) pode bloquear facilmente a GUI se for executado no encadeamento da GUI. Para garantir a capacidade de resposta da interface do usuário , um processo pesado pode ser executado de forma assíncrona. É melhor executar operações assíncronas semelhantes, uma de cada vez . por exemplo, várias operações vinculadas à IO podem ser significativamente mais lentas se executadas ao mesmo tempo, por isso é melhor enfileirá- las para começar
- uma tarefa ou um lote de tarefas é executada em outro encadeamento
- um tempo
- se houver uma tarefa, não haverá sequência; então, você deve esperar que ela termine ou dispara e esquece
- se é um lote de tarefas, você dispara e esquece tudo ao mesmo tempo, espera que tudo termine ou executa cada conclusão da tarefa para iniciar
- reduz essencialmente o desempenho por causa das despesas gerais
- fornece capacidade de resposta a outro thread (eficaz contra o bloqueio do thread da interface do usuário ou outros threads essenciais)
Nota: uma operação assíncrona que é executada simultaneamente (ou seja, mais de uma vez por vez) é uma operação simultânea.
Nota: A simultaneidade e a assíncrona geralmente são confundidas entre si. A simultaneidade refere-se a diferentes partes do sistema trabalhando juntas sem interferir umas com as outras (esses problemas geralmente são resolvidos com bloqueios, semáforos ou mutexes). Assíncrona é como você obtém capacidade de resposta (como o encadeamento).
* Nota: Assíncrona e Multithreading são frequentemente confundidas entre si. O código assíncrono não envolve necessariamente um novo thread. pode ser uma operação de hardware ou, como Stephan chama de operação pura, leia este
por exemplo, no código WPF + C # abaixo, await Task.Run(()=> HeavyMethod(txt))
está resolvendo um problema de assincronia, enquanto textBox.Dispatcher.Invoke
está resolvendo um problema de simultaneidade:
private async void ButtonClick(object sender, RoutedEventArgs e)
{
// run a method in another thread
await Task.Run(()=> HeavyMethod(txt));
// modify UI object in UI thread
txt.Text = "done";
}
// This is a thread-safe method. You can run it in any thread
internal void HeavyMethod(TextBox textBox)
{
while (stillWorking)
{
// use Dispatcher to safely invoke UI operations
textBox.Dispatcher.Invoke(() =>
{
// UI operations outside of invoke will cause ThreadException
textBox.Text += ".";
});
}
}