Pergunta

Eu vi uma pergunta sobre o porquê de "polling é ruim". Em termos de minimizar a quantidade de tempo de processador usado por um fio, seria melhor para fazer uma espera de spin (ou seja, votação para uma mudança necessária em um loop while) ou espera em um objeto de kernel (por exemplo, um kernel objeto de evento no Windows) ?

Para contexto, assumem que o código seria necessário para rodar em qualquer tipo de processador, de núcleo único, HyperThreaded, multicore, etc. Também assumem que um segmento que iria sondar ou espera não pode continuar até que o resultado de pesquisa é satisfatória se ele entrevistou, em vez de espera. Finalmente, o tempo entre quando um fio começa em espera (ou polling) e quando a condição é satisfeita potencialmente pode variar de um tempo muito curto para um longo tempo.

Uma vez que o sistema operacional é provável que de forma mais eficiente "poll" no caso de "espera", eu não quero ver o "esperando apenas significa que alguém faz o polling" argumento, isso é notícia velha, e não é necessariamente 100% exato.

Foi útil?

Solução

Desde que o sistema operacional tem implementações razoáveis ??deste tipo de primitivas de concorrência, é definitivamente melhor esperar em um objeto kernel.

Entre outras razões, isso permite que o OS sabe que não deve agendar o fio em questão para timeslices adicionais até que o objeto ser esperou-for está no estado apropriado. Caso contrário, você tem uma discussão que está constantemente sendo remarcada, o contexto mudado-se, e depois de correr por um tempo.

Você perguntou especificamente sobre minimizando o tempo de processador para um segmento: neste exemplo o segmento de bloqueio em um objeto de kernel usaria ZERO tempo; o fio de votação iria usar todos os tipos de tempo.

Além disso, a "outra pessoa é polling" necessidade argumento não ser verdade. Quando um objeto de kernel entra no estado apropriado, o kernel pode olhar para ver naquele instante que segmentos estão aguardando para esse objeto ... e, em seguida, agendar um ou mais deles para a execução. Não há nenhuma necessidade para o kernel (ou qualquer outra pessoa) para poll nada neste caso.

Outras dicas

Esperar é o caminho "mais agradável" se comportar. Quando você está à espera de um kernel objeto seu segmento não será concedido qualquer tempo de CPU, como é conhecido pelo programador que não há trabalho pronto. Seu segmento só vai ser dado tempo de CPU quando da condição de espera é satisfeita. O que significa que você não vai ser monopolizando recursos da CPU desnecessariamente.

Eu acho que um ponto que não tenha sido levantada ainda é que, se o seu sistema operacional tem um monte de trabalho a fazer, bloqueando yeilds seu segmento para outro processo. Se todos os processos utilizam as primitivas de bloqueio onde eles devem (como do kernel espera, arquivo / network IO etc.) que você está dando o kernel mais informações para escolher quais tópicos devem executar. Como tal, ele vai fazer mais trabalho na mesma quantidade de tempo. Se a sua aplicação poderia estar fazendo algo de útil enquanto espera para esse arquivo para abrir ou o pacote para chegar em seguida, Yeilding vai mesmo ajudar você próprio aplicativo.

Espera envolve mais recursos e significa um interruptor de contexto adicional. De fato, algumas primitivas de sincronização, como monitores CLR e seções críticas Win32 usam um protocolo de bloqueio em duas fases - alguns espera rotação é feito tona realmente fazendo um verdadeiro espera

.

Eu imagino fazendo a coisa de duas fases seria muito difícil, e envolveria muitos testes e pesquisas. Então, a menos que você tem o tempo e recursos, para manter as primitivas janelas ... eles já fez a pesquisa para você.

Existem apenas alguns lugares, geralmente dentro das coisas OS de baixo nível (manipuladores de interrupção / drivers de dispositivo), onde faz sentido esperar spin-/ é necessária. aplicações de uso geral são sempre melhor esperar em algumas primitivas de sincronização como mutexes / variáveis ??condicionais / semáforos.

Eu concordo com Darksquid, se o seu sistema operacional tem primitivas de concorrência decente, então você não deve precisar de votação. polling geralmente vem em seu próprio em sistemas de tempo real ou hardware restrito que não tem um sistema operacional, então você precisa para pesquisa, porque você pode não ter a opção de wait (), mas também porque lhe dá grãos pequenos controle sobre exatamente quanto tempo você quer esperar em um determinado estado, ao contrário de estar à mercê do programador.

Espera (bloqueio) é quase sempre a melhor escolha ( "melhor" no sentido de fazer uso eficiente dos recursos de processamento e minimizando o impacto para outro código em execução no mesmo sistema). As principais exceções são:

  1. Quando a duração de polling esperado é pequena (similar em magnitude ao custo do syscall de bloqueio).
  2. Principalmente em sistemas embarcados, quando a CPU é dedicada à realização de uma tarefa específica e não há vantagem em ter o ocioso CPU (por exemplo, alguns roteadores de software construídas no final dos anos 90 usado essa abordagem.)

Polling, geralmente não é usado dentro OS kernels para implementar o bloqueio de chamadas do sistema -. Em vez disso, eventos (interrupções, temporizadores, ações em semáforos) resultam em um processo bloqueado ou thread que está sendo feito executável

Há quatro abordagens básicas pode-se tomar:

  1. Use algum OS esperando primitiva que esperar até que o evento ocorre
  2. Use algum temporizador OS primitiva para verificar em algum taxa definida se o evento ocorreu ainda
  3. verificar repetidamente se o evento ocorreu, mas usar um sistema operacional primitivo para produzir uma fatia de tempo por um período arbitrário e desconhecido qualquer momento ele não tem.
  4. verificar repetidamente se o evento ocorreu, sem ceder a CPU se não tem.

Ao nº 1 é prático, é muitas vezes a melhor abordagem a menos atrasar a resposta de um para o evento pode ser benéfico. Por exemplo, se um está à espera de receber uma grande quantidade de dados de porta serial ao longo de vários segundos, e se o processamento de 100ms de dados depois de ser enviado será tão bom como processá-lo instantaneamente, polling periódico usando um dos dois últimos abordagens pode ser melhor do que a criação de um "dados recebidos" do evento.

Abordagem # 3 é bastante rudimentar, mas pode, em muitos casos, ser uma boa. É, muitas vezes, perder mais tempo de CPU e recursos do que se aproximaria # 1, mas em muitos casos, ser mais simples de implementar e o desperdício de recursos em muitos casos, ser pequeno o suficiente para não importa.

Abordagem nº 2 é muitas vezes mais complicado do que # 3, mas tem a vantagem de ser capaz de lidar com muitos recursos com um único temporizador e nenhum segmento dedicado.

Abordagem nº 4 às vezes é necessário em sistemas embarcados, mas é geralmente muito ruim a menos que um é diretamente hardware polling ea não terá nada de útil para fazer até que o evento em questão ocorre. Em muitas circunstâncias, não será possível para a condição a ser esperou mediante a ocorrer até o fio esperando por ele produz o CPU. Produzindo o CPU como na abordagem # 3 irá de fato permitir que o segmento de espera para ver o evento mais cedo do que seria monopolizando-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top