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:

https://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).