Spinlock (Parte I)

Tenho recebido uma série de emails perguntando sobre SPINLOCK e infelizmente não tive tempo para escrever muito sobre o assunto. Há um post antigo: Spinlock Contention, mas vejo que falta mais coisa. Vou escrever esse artigo para dar uma idéia sobre o spinlock e, em seguida, mostrarei seu funcionamento.

Primeiro, devemos traduzir literalmente a palavra spinlock:

  • SPIN = Rodar
  • LOCK = Bloqueio

Isso dá uma pista inicial de que a estrutura de Spinlock corresponde a um lock na qual a thread fica rodando, muito semelhante a um loop infinito.

Em T-SQL, isso corresponde a um código assim:

 SET LOCK_TIMEOUT 0

SpinLoop:
    
    UPDATE tabela SET coluna = 'bla'
    IF @@ERROR <>0 goto SpinLoop   

Analisando o código em uma situação na qual a tabela está bloqueada, observamos que esse código utiliza um LOOP INFINITO até que a tabela seja atualizada.

Meu experimento foi colocar um bloqueio propositalmente na tabela e em seguida rodar o SpinLock. O resultado foram 34074 mensagens repetidas como apresentadas abaixo, podendo dizer assim que houve 1 colisão e 34074 spins:

 Msg 1222, Level 16, State 56, Line 3
Lock request time out period exceeded.
Msg 1222, Level 16, State 56, Line 3
Lock request time out period exceeded.
Msg 1222, Level 16, State 56, Line 3
Lock request time out period exceeded.
...
Msg 1222, Level 16, State 56, Line 3
Lock request time out period exceeded.

A vantagem desse código é que nenhum LOCK é efetivamente utilizado. Por outro lado, a CPU vai para 100% imediatamente.

O OBJETIVO DESSE CÓDIGO É ILUSTRAR A IDÉIA POR TRÁS DO SPINLOCK. JAMAIS USE ESTE CÓDIGO!

No próximo post, colocarei a descrição do “verdadeiro” spinlock.

Comments

  • Anonymous
    July 13, 2010
    The comment has been removed

  • Anonymous
    July 14, 2010
    Olá Leivio! Muito bom saber que você gosta de programar em C++. O spinlock é uma proteção de acesso concorrente de threads, exatamente como você falou. Ela existe no código do SQL Server, no Kernel do Windows, no Linux (com as pthreads), etc. Fazendo um paralelo com o Windows, veja a documentação da função InitializeCriticalSectionAndSpinCount em como funciona o parâmetro SpinCount. Existem várias formas de implementar um Spinlock. Recentemente, o SQL Server tem adotado um modelo de "exponential back-offs". Existem papers disponíveis no mundo acadêmico que discutem os ganhos disso tudo, mas dá uma olhada nesse artigo da Intel. software.intel.com/.../implementing-scalable-atomic-locks-for-multi-core-intel-em64t-and-ia32-architectures Espero que isso aumente sua curiosidade no assunto. Abraços, Fabricio

  • Anonymous
    July 14, 2010
    Muito interessante Fabrício. Se possível, podes demonstrar o SpinLock na prática? Tipo: mostrar quando ele pode gerar 100%¨CPU em um servidor SQL e como identificar possíveis problemas relativos ao mesmo? Abraço

  • Anonymous
    July 15, 2010
    The comment has been removed

  • Anonymous
    July 19, 2010
    Valeu Luti! Bom falar com você! O exemplo do IDENTITY é um bom cenário, mas há um detalhe: todas as operações são logadas em disco e, por isso, o processo de incremento é feito usando um mecanismo de Latch. A idéia é isso mesmo!!! Um bom exemplo de Spinlock é na atualização dos contadores do Performance Monitor, no qual as variáveis são incrementadas de forma atômica. Qualquer sincronização que dura milissegundos utiliza Latches, enquanto que os mecanismos de nanossegundos usam spinlocks. Obrigado - Fabricio

  • Anonymous
    July 23, 2014
    Grande mestre Catae. Valeu pela explicação