Qual a diferença entre o spinlock e a pesquisa?


41

Spinlock e polling são a mesma coisa?

Wikipedia:

um spinlock é um bloqueio que faz com que um encadeamento que tenta adquiri-lo simplesmente espere em um loop ("rotação") enquanto verifica repetidamente se o bloqueio está disponível

Isso soa muito parecido com:

while(!ready);

Fui ensinado a evitar pesquisas sempre que possível, pois era totalmente sub-ideal. Então, spinlock é um nome sofisticado para pesquisas antigas ruins? Como um spinlock é diferente da pesquisa?

Respostas:


85

A pesquisa refere-se à verificação repetida se um recurso ( qualquer tipo de recurso) está pronto.

Um spinlock é quando o recurso que você está pesquisando é um bloqueio.

Observe que a pesquisa não é ruim. Em particular, a pesquisa é eficiente quando geralmente há dados prontos quando você pesquisa. A pesquisa é apenas ineficiente se você fizer isso sem obter nenhum dado em troca.

Por outro lado, as interrupções são ineficientes se houver tantos dados que você é constantemente interrompido. Eles são eficientes se os dados chegarem raramente o suficiente para que você possa realmente realizar algum trabalho útil antes de ser interrompido.

Posso dar um exemplo da vida real a partir de minha própria experiência: 15 anos atrás, eu tinha meu programa de e-mail configurado para me interromper toda vez que um novo e-mail entra. O que acontecia uma ou duas vezes por semana. Verificar constantemente minha caixa de entrada seria uma perda colossal de tempo.

Atualmente, tenho todas as notificações desativadas. Eu sei que sempre que eu olhar para minha caixa de entrada, haverá novos e-mails lá. A pesquisa é muito mais eficiente agora.

Spinlocks são eficientes quando: a) a probabilidade de a trava é baixa eb) se a trava for realizada, ela será mantida apenas por um curto período de tempo. Em outras palavras: é eficiente para bloqueios de granulação fina não contidos, mas ineficiente para bloqueios de granulação grossa altamente contidos.

(E, é claro, os spinlocks funcionam apenas quando existe um paralelismo verdadeiro; caso contrário, o outro thread não terá a chance de liberar o bloqueio. Acho que isso é óbvio, mas eu queria afirmar de qualquer maneira.)


5
Spinlocks podem ser perfeitamente sensíveis em um ambiente multitarefa cooperativamente. Você só precisa ter certeza de que está cedendo controle no loop.
Kevin

4
Ótimo exemplo com e-mails. Lembra-me de você sempre tem e-mail ...
Petr Pudlak

2
@ Kevin: Eu tenho uma idéia muito purista de um spinlock, literalmente um cadeado que gira em um loop vazio. ( atomically_do { while (lock.is_locked?); lock.acquire! }) Se ceder, não é um loop vazio e, portanto, não é um spinlock nessa visão purista :-D Mas é claro que alguma hibridação com outros tipos de bloqueios ou relaxamentos / acréscimos ao ideal platônico faz todo o sentido no mundo real.
Jörg W Mittag

3
@bubakazouba: Um spinlock funciona literalmente "girando" em um loop vazio e verifica "O bloqueio ainda está liberado? O bloqueio já está liberado? O bloqueio já está liberado? O bloqueio já está liberado? O bloqueio já está liberado? repetidamente. Se não houver paralelismo, não haverá outro encadeamento em execução ao mesmo tempo que possa liberar o bloqueio, para que você tenha efetivamente um loop sem fim! Veja o comentário diretamente acima do seu.
Jörg W Mittag

1
@kasperd: Você ainda pode ver multitarefa cooperativa em software de servidor orientado a eventos como o nginx. Nesse caso, há um encadeamento e nenhum bloqueio, o que significa que você só pode explorar um núcleo. Que eu saiba, não existem literalmente exemplos reais da verdadeira multitarefa cooperativa multicore. Esse sistema seria estúpido, já que você obteria todas as desvantagens da multitarefa cooperativa sem a vantagem de não haver bloqueios.
27415 Kevin

10

Um spinlock é um tipo de bloqueio, especificamente, obtido por meio de pesquisa.

A pesquisa é um método de verificar o status de algo (solicitando o status, em vez de esperar que o status seja informado).

Nem toda pesquisa é um spinlock, por exemplo, pesquisa o status das teclas do teclado.


Além disso, a pesquisa não é inerentemente ruim. Períodos muito curtos de pesquisa podem evitar mudanças caras de contexto que o uso de interrupções exigiria, sem mencionar que as pesquisas às vezes podem ser mais simples de implementar e, portanto, mais fáceis de manter, especialmente em níveis mais baixos. Como sempre, absolutos são uma coisa terrível, e você deve usar o método que ofereça o desempenho / complexidade apropriado para suas necessidades, conforme você as mediu , em vez de usar ou descartar cegamente as opções.


5

O spinlock é diferente da pesquisa porque ocorre apenas por um período muito curto, da ordem de alguns milissegundos ou menos. A pesquisa pode continuar indefinidamente.

Na programação paralela, um breve episódio de rotação é geralmente preferível ao bloqueio, pois evita o custo da alternância de contexto e das transições do kernel.

Leitura adicional
SpinLock e SpinWait em C #
Spinlocks e bloqueios de leitura e gravação em C


Eu acho que você quis dizer microssegundos. Para um bloqueio que dura um milissegundo inteiro, devemos usar uma implementação de bloqueio que faça uma chamada do kernel em contenção.
Peter

@ Peter Talvez seja o que Albahari quis dizer. É o que o texto dele diz.
Robert Harvey

4

A diferença é que um spinlock é (esperançosamente) usado apenas em situações em que é apropriado e, nessas situações, é muito eficiente.

Você usa um spinlock se espera que um recurso seja bloqueado apenas por um período muito curto - por exemplo, se um bloqueio for usado apenas para atualizar uma variável. O spinlock controla o bloqueio na velocidade máxima, mas esperamos que por menos de microssegundos. Um mutex normal exigiria na chamada do SO. Se o bloqueio for mantido apenas por um período de tempo pequeno, o spinlock usará apenas um tempo de CPU, enquanto a chamada do sistema operacional levará mais tempo. Mas se essa expectativa estiver errada, o spinlock será muito ineficiente - ele usará 100% de tempo da CPU em uma CPU, enquanto o mutex normal leva apenas um tempo para entrar no sistema operacional e retornar.

Às vezes, ambos são combinados; você executa o bloqueio de rotação por um curto período de tempo e muda para uma estratégia diferente se o bloqueio de rotação não funcionar.


2

Pesquisas excessivas são algo que você não deve fazer porque desperdiça recursos do sistema. Daqui resulta que a pesquisa é boa se não desperdiçar recursos do sistema .

Por exemplo, pesquisas excessivas levarão a carga da CPU a 100% nos casos em que o trabalho real resultaria em apenas 2%.

A pesquisa pode ser usada para outras coisas que não while(!ready). Por exemplo, significa verificar regularmente se o usuário pressionou uma tecla. Uma implementação sã verificará no máximo uma vez a cada 15 milissegundos, por isso é uma verificação a cada ~ 20 milhões de ciclos de clock. Esse tipo de pesquisa é excelente, porque não desperdiça recursos do sistema.

Um SpinLock não é um caso especial. Se tivermos um SpinLock e um segmento entrar no bloqueio e outro tiver que esperar, o SpinLock é a escolha errada se e somente se o segmento em espera desperdiçar recursos do sistema. O encadeamento em espera desperdiçará recursos do sistema se, e somente se, tiver que aguardar uma quantidade significativa de tempo antes de poder obter o bloqueio.

Portanto, o uso de um SpinLock para proteger qualquer coisa que exija alguns milhares de ciclos de clock ou mais antes de desbloquear novamente (por exemplo, compilar e executar um pedaço de javascript em tempo real) é ruim, exatamente pelo motivo que você declarou. Mas usar um SpinLock para proteger algo que é concluído rapidamente, como acessar um mapa de hash corretamente implementado, é bom porque o encadeamento em espera gira apenas 2 ou 3 vezes e, portanto, não desperdiça recursos do sistema.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.