Spinlock (Parte II)


No post anterior, fiquei um pouco receoso sobre meu comentário falando de spinlock usando T-SQL. A razão disso é que SPINLOCK não tem nada a ver com linguagens de alto nível, porém, está diretamente relacionado com a arquitetura de processador e códigos em assembly. Por isso, a melhor referência são os fabricantes de processadores, como a Intel e AMD.

Há um exemplo bastante simples no manual da Intel:

http://www.intel.com/Assets/PDF/manual/248966.pdf

Spin_Lock:
    CMP lockvar, 0 ; // Check if lock is free.
    JE Get_lock
    PAUSE; // Short delay.
    JMP Spin_Lock;
Get_Lock:
    MOV EAX, 1;
    XCHG EAX, lockvar; // Try to get lock.
    CMP EAX, 0; // Test if successful.
    JNE Spin_Lock;

Critical_Section:
    <critical section code>
MOV lockvar, 0; // Release lock.

O trecho Get_Lock (em vermelho) corresponde a um loop infinito implementado usando apenas 4 instruções assembly. Normalmente, assume-se que o spinlock apresentará um baixo número de colisões e poucos spins.

Vamos supor que para cada tentativa de obter um spinlock haja uma média de 10 spins e que correspondem a 80 ciclos de CPU.

Qual é a alternativa ao spinlock? O sistema operacional disponibiliza os objetos de Eventos, Mutex, Semáforos, etc. Ao usar esses objetos, gastam-se pelo menos 200 ciclos de CPU para fazer a transição com a Kernel e ainda há a possibilidade de ocorrer um Context Switch na Thread.

Aqui vem a questão: o que é melhor usar, um spinlock ou uma primitiva do sistema operacional? A resposta é depende. Em geral, o spinlock apresenta uma performance melhor do que os objetos de eventos e mutex. Por outro lado, há casos no qual o spinlock apresenta um número muito alto de colisões e spins, que degrada sua performance.

O fato é que o controle de Spinlock não está nas mãos do DBA e sim, na arquitetura do produto. Por outro lado, podemos sempre realizar uma monitoração periódica dos spinlocks usando o comando DBCC SQLPERF(SPINLOCKSTATS) para detectar problemas e gargalos do SQL, com o intuito de tentar contorná-los.

Há ainda mais um post sobre o assunto de spinlocks.

Enquanto isso, gostaria de adiantar algo: Você já ouviu falar de WAITSTATS? Há uma estrutura denominada LATCH e ela corresponde às primitivas do Sistema Operacional (Eventos, Semáforos e Mutex).

Comments (6)

  1. DBA SQL disse:

    Fabrício, no próximo post você poderia dar exemplos de como verificamos problemas e gargalos no SQL via SpinLocks?

    Abraços

  2. Boa idéia!!! Obrigado, Fabricio

  3. Leivio disse:

    Fabricio,

    Excelente.!

    Complementando a seguinte questão: "O que é melhor usar, um spinlock ou uma primitiva do sistema operacional?" complementado a sua resposta. Acredito que depende principalmente do tipo de recurso que estou colocando na região critica e qual a estimativa de tempo em que essa região será exclusiva. Ou seja, Spinlock é mais eficiente em pequenos bloqueios onde o tempo maximo seria  o quantum dado a thread de acordo com sua arquitetura de CPU/SO!

    Pelo que sei…os WAITS do tipo LATCH são operações que ocorrem em memoria. Bloqueios para o tipo LATCH são uma proteção da pagina de dados enquanto a mesma ainda está na memoria.

    Referencias:

    http://www.koders.com/…/fidD3FB067877521C26AC39D985B687ECB255D1A6DA.aspx

    Fabricio,

    Muito bom o nivel do blog. Queria que tivessemos eventos de bom nivel aqui em Fortaleza.

    Abraços,

    Leivio Fontenele

  4. Oi Leivio!

    Não conhecia esse link do código do .NET Framework com a implementação de um spinlock. Vi que está implementado o backoff e a chamada ao YieldProcessor para deixar hyper-thread friendly. Seu comentário é exatamente aquilo que queria dizer, mas não consegui expressar de forma tão direta:

    "O que é melhor usar, um spinlock ou uma primitiva do sistema operacional?" complementado a sua resposta. Acredito que depende principalmente do tipo de recurso que estou colocando na região critica e qual a estimativa de tempo em que essa região será exclusiva. Ou seja, Spinlock é mais eficiente em pequenos bloqueios onde o tempo maximo seria  o quantum dado a thread de acordo com sua arquitetura de CPU/SO!

    Latches é uma classe dos bloqueios que ocorrem em memória (PAGEPATCH) e de todos os outros bloqueios, incluindo espera por rede, DTC, disco, profiler, etc. Pretendo escrever um pouco mais sobre os latches porque eles sim são conceitos chaves para qualquer diagnóstico de performance. Obrigado por compartilhar seus comentários.. isso adiciona muito valor ao conteúdo do blog.

    Abraços, Fabricio

  5. Leivio disse:

    Eu que agradeço por mais esses espaço com bons topicos sobre SQL Server. 🙂

    []´s

    Leivio Fontenele

Skip to main content