Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este documento descreve as diferenças entre os recursos e modelos de programação do Concurrency Runtime e outras tecnologias. Ao entender como os benefícios do Concurrency Runtime se comparam aos benefícios de outros modelos de programação, você pode selecionar a tecnologia que melhor satisfaz os requisitos de seus aplicativos.
Se você estiver usando outro modelo de programação, como o pool de threads do Windows ou o OpenMP, há situações em que pode ser apropriado migrar para o Concurrency Runtime. Por exemplo, o tópico Migrando do OpenMP para o Concurrency Runtime descreve quando pode ser apropriado migrar do OpenMP para o Concurrency Runtime. No entanto, se estiveres satisfeito com o desempenho da aplicação e o suporte à depuração atual, a migração não será necessária.
Você pode usar os recursos e os benefícios de produtividade do Concurrency Runtime para complementar seu aplicativo existente que usa outro modelo de simultaneidade. O Concurrency Runtime não pode garantir o balanceamento de carga quando vários agendadores de tarefas competem pelos mesmos recursos de computação. No entanto, quando as cargas de trabalho não se sobrepõem, esse efeito é mínimo.
Secções
Comparando o Agendamento Preventivo com o Agendamento Cooperativo
Comparando o tempo de execução de simultaneidade com a API do Windows
Comparando o Agendamento Preventivo com o Agendamento Cooperativo
O modelo preventivo e os modelos de agendamento cooperativo são duas maneiras comuns de permitir que várias tarefas compartilhem recursos de computação, por exemplo, processadores ou threads de hardware.
Agendamento preventivo e cooperativo
O agendamento preventivo é um mecanismo round-robin, baseado em prioridades, que dá a cada tarefa acesso exclusivo a um recurso de computação por um determinado período de tempo e, em seguida, alterna para outra tarefa. O agendamento preventivo é comum em sistemas operacionais multitarefa, como o Windows. O agendamento cooperativo é um mecanismo que dá a cada tarefa acesso exclusivo a um recurso de computação até que a tarefa termine ou até que a tarefa produza seu acesso ao recurso. O Concurrency Runtime usa o agendamento cooperativo juntamente com o agendador preventivo do sistema operacional para obter o máximo uso de recursos de processamento.
Diferenças entre programadores preventivos e cooperativos
Os agendadores preventivos procuram dar a vários threads acesso igual aos recursos de computação para garantir que cada thread faça progresso. Em computadores que dispõem de muitos recursos informáticos, a garantia de um acesso equitativo torna-se menos problemática; No entanto, garantir uma utilização eficiente dos recursos torna-se mais problemático.
Um agendador de modo kernel preventivo requer que o código do aplicativo dependa do sistema operacional para tomar decisões de agendamento. Por outro lado, um agendador cooperativo de modo de usuário permite que o código do aplicativo tome suas próprias decisões de agendamento. Como o agendamento cooperativo permite que muitas decisões de agendamento sejam tomadas pelo aplicativo, ele reduz grande parte da sobrecarga associada à sincronização no modo kernel. Um agendador cooperativo normalmente adia as decisões de agendamento para o kernel do sistema operacional quando não tem outro trabalho para agendar. Um escalonador cooperativo também remete para o escalonador do sistema operativo quando há uma operação de bloqueio que é comunicada ao kernel, mas essa operação não é comunicada ao escalonador em modo de utilizador.
Programação Cooperativa e Eficiência
Para um agendador preventivo, todo o trabalho que tem o mesmo nível de prioridade é igual. Um agendador preventivo normalmente agenda threads na ordem em que são criados. Além disso, um agendador preventivo dá a cada thread uma fatia de tempo de forma round-robin, com base na prioridade do thread. Embora este mecanismo proporcione equidade (cada segmento avança), ele tem algum custo de eficiência. Por exemplo, muitos algoritmos de computação intensiva não exigem equidade. Em vez disso, é importante que as tarefas relacionadas terminem no menor tempo total. O agendamento cooperativo permite que um aplicativo agende o trabalho de forma mais eficiente. Por exemplo, considere um aplicativo que tenha muitos threads. O agendamento de threads que não compartilham recursos para execução simultânea pode reduzir a sobrecarga de sincronização e, assim, aumentar a eficiência. Outra maneira eficiente de agendar tarefas é executar pipelines de tarefas (onde cada tarefa atua na saída da anterior) no mesmo processador para que a entrada de cada estágio de pipeline já esteja carregada no cache de memória.
Usando o agendamento preventivo e cooperativo juntos
O agendamento cooperativo não resolve todos os problemas de agendamento. Por exemplo, as tarefas que não cedem de forma justa a outras tarefas podem consumir todos os recursos de computação disponíveis e impedir que outras tarefas progridam. O Concurrency Runtime usa os benefícios de eficiência do agendamento cooperativo para complementar as garantias de equidade do agendamento preventivo. Por padrão, o Concurrency Runtime fornece um agendador cooperativo que usa um algoritmo de roubo de trabalho para distribuir eficientemente o trabalho entre os recursos de computação. No entanto, o agendador Concurrency Runtime também depende do agendador preventivo do sistema operacional para distribuir recursos de forma justa entre os aplicativos. Você também pode criar agendadores personalizados e políticas de agendador em seus aplicativos para produzir controle refinado sobre a execução de threads.
[Topo]
Comparando o tempo de execução de simultaneidade com a API do Windows
A interface de programação de aplicativos do Microsoft Windows, que normalmente é chamada de API do Windows (e anteriormente conhecida como Win32), fornece um modelo de programação que permite a simultaneidade em seus aplicativos. O Concurrency Runtime baseia-se na API do Windows para fornecer modelos de programação adicionais que não estão disponíveis no sistema operacional subjacente.
O Concurrency Runtime baseia-se no modelo de thread da API do Windows para executar trabalho paralelo. Ele também utiliza o gerenciamento de memória da API do Windows e os mecanismos de armazenamento local de thread. No Windows 7 e no Windows Server 2008 R2, ele usa o suporte à API do Windows para threads escalonáveis pelo usuário e computadores com mais de 64 threads de hardware. O Concurrency Runtime estende o modelo de API do Windows fornecendo um agendador de tarefas cooperativo e um algoritmo de roubo de trabalho para maximizar o uso de recursos de computação e habilitando várias instâncias de agendador simultâneas.
Linguagens de Programação
A API do Windows usa a linguagem de programação C para expor o modelo de programação. O Concurrency Runtime fornece uma interface de programação C++ que aproveita os recursos mais recentes da linguagem C++. Por exemplo, as funções lambda fornecem um mecanismo sucinto e seguro para definir funções de trabalho paralelas. Para obter mais informações sobre os recursos C++ mais recentes que o Concurrency Runtime usa, consulte Visão geral.
Threads e Pool de Threads
O mecanismo de simultaneidade central na API do Windows é o thread. Normalmente, você usa a função CreateThread para criar threads. Embora os threads sejam relativamente fáceis de criar e usar, o sistema operacional aloca uma quantidade significativa de tempo e outros recursos para gerenciá-los. Além disso, embora cada thread tenha a garantia de receber o mesmo tempo de execução que qualquer outro thread no mesmo nível de prioridade, a sobrecarga associada requer que você crie tarefas suficientemente grandes. Para tarefas menores ou mais refinadas, a sobrecarga associada à simultaneidade pode superar o benefício de executar as tarefas em paralelo.
Os pools de threads são uma maneira de reduzir o custo do gerenciamento de threads. Os pools de threads personalizados e a implementação do pool de threads fornecida pela API do Windows permitem que pequenos itens de trabalho sejam executados com eficiência em paralelo. O pool de threads do Windows mantém itens de trabalho em uma fila de espera FIFO (primeiro a entrar, primeiro a sair). Cada item de trabalho é iniciado na ordem em que foi adicionado ao pool.
O Concurrency Runtime implementa um algoritmo de roubo de trabalho para estender o mecanismo de agendamento FIFO. O algoritmo move tarefas que ainda não começaram para threads que ficam sem itens de trabalho. Embora o algoritmo de roubo de trabalho possa equilibrar cargas de trabalho, ele também pode fazer com que os itens de trabalho sejam reordenados. Esse processo de reordenação pode fazer com que um item de trabalho seja iniciado em uma ordem diferente da que foi enviado. Isso é útil com algoritmos recursivos, onde há uma chance maior de que os dados sejam compartilhados entre tarefas mais recentes do que entre as mais antigas. Fazer com que os novos itens sejam executados primeiro significa menos falhas de cache e, possivelmente, menos falhas de página.
Do ponto de vista do sistema operacional, o roubo de trabalho é injusto. No entanto, quando um aplicativo implementa um algoritmo ou tarefa para ser executado em paralelo, a equidade entre as subtarefas nem sempre importa. O que importa é a rapidez com que a tarefa geral termina. Para outros algoritmos, o FIFO é a estratégia de agendamento adequada.
Comportamento em vários sistemas operacionais
No Windows XP e no Windows Vista, os aplicativos que usam o Tempo de Execução de Simultaneidade se comportam de forma semelhante, exceto que o desempenho de pilha é melhorado no Windows Vista.
No Windows 7 e no Windows Server 2008 R2, o sistema operacional suporta ainda mais simultaneidade e escalabilidade. Por exemplo, esses sistemas operacionais suportam computadores que têm mais de 64 threads de hardware. Um aplicativo existente que usa a API do Windows deve ser modificado para aproveitar esses novos recursos. No entanto, um aplicativo que usa o Concurrency Runtime usa automaticamente esses recursos e não requer modificações.
base.agendamento-em-modo-utilizador
[Topo]
Comparando o Concurrency Runtime com o OpenMP
O Concurrency Runtime permite uma variedade de modelos de programação. Estes modelos podem sobrepor-se ou complementar os modelos de outras bibliotecas. Esta seção compara o Concurrency Runtime com o OpenMP.
O modelo de programação OpenMP é definido por um padrão aberto e tem ligações bem definidas para as linguagens de programação Fortran e C/C++. As versões 2.0 e 2.5 do OpenMP são adequadas para algoritmos paralelos que são iterativos; ou seja, eles executam iteração paralela sobre uma matriz de dados. OpenMP é mais eficiente quando o grau de paralelismo é pré-determinado e corresponde aos recursos disponíveis no sistema. O modelo OpenMP é uma combinação especialmente boa para computação de alto desempenho, onde problemas computacionais muito grandes são distribuídos pelos recursos de processamento de um único computador. Nesse cenário, o ambiente de hardware é conhecido e o desenvolvedor pode razoavelmente esperar ter acesso exclusivo aos recursos de computação quando o algoritmo é executado.
No entanto, outros ambientes de computação menos restritos podem não ser uma boa combinação para o OpenMP. Por exemplo, problemas recursivos (como o algoritmo quicksort ou a pesquisa de uma árvore de dados) são mais difíceis de implementar usando OpenMP. O Concurrency Runtime complementa os recursos do OpenMP fornecendo a Biblioteca de Padrões Paralelos (PPL) e a Biblioteca de Agentes Assíncronos. Ao contrário do OpenMP, o Concurrency Runtime fornece um agendador dinâmico que se adapta aos recursos disponíveis e ajusta o grau de paralelismo à medida que as cargas de trabalho mudam.
Muitos dos recursos no Concurrency Runtime podem ser estendidos. Você também pode combinar recursos existentes para compor novos. Como o OpenMP depende de diretivas de compilador, ele não pode ser estendido facilmente.
Para obter mais informações sobre como o Concurrency Runtime se compara ao OpenMP e como migrar o código OpenMP existente para usar o Concurrency Runtime, consulte Migrando do OpenMP para o Concurrency Runtime.
[Topo]
Ver também
Runtime de Concorrência
Descrição geral
Biblioteca de Padrões Paralelos (PPL)
Biblioteca de agentes assíncronos
OpenMP