2011-01-19 2 views
6

Understanding the Linux kernel (Bovet & Cesati),을 통해 읽기 이래로 커널 동기화에 대한 장 스핀 락 취득 코드로 귀결한다고 :Linux/SMP 스핀 록이 불필요하게 느린가요?

1: lock: 
    btsl $0, slp 
    jnc  3 
2: testb $1, slp 
    jne  2 
    jmp  1 
3: 
이제

내가 원래 중첩 루프를 가지고 낭비 듯 생각 당신이 뭔가를 구현할 수 :

1: lock: 
    btsl $0, slp 
    jc  1 

훨씬 더 간단합니다. 그러나 lock이 다른 CPU에 영향을 미치고 btsl의 타이밍이 단순한 testb의 것보다 크기 때문에 그 이유를 알 수 있습니다.

내가 을 가지고 있지 않은 한 가지가은 스핀 락의 후속 릴리스입니다.

lock: 
    btrl $0, slp 

내 질문은 기본적으로 이유 :이 책은 다음과 같은 산출한다고?lock/mov-immediate 콤보가 더 빠릅니다.

커널이 버그가 없다는 규칙에 따라 이전 상태를 1로 설정하므로 이전 상태를 캐리 플래그로 가져올 필요가 없습니다. 당신이 이미 그것을 습득하지 않았다면 그것을 풀어 주려고하지 않을 것입니다).

그리고 mov 적어도 내가 무엇을 놓치고 그래서 386

에, btrl보다 훨씬 빠르다?

이후 칩의 지침에 대한 타이밍이 변경 되었습니까?

책을 인쇄 한 후 커널이 업데이트 되었습니까?

도서가 잘못 되었습니까?

더 빠른 명령이 만족하지 않는 CPU 간의 동기화를 포함한 다른 측면을 놓쳤습니까?

답변

10

글쎄, Understanding the Linux Kernel입니다. 작성된 이래로 Linux 커널은 티켓 스핀 록 (ticket spinlocks)을 사용하도록 업데이트되었습니다. 잠금 장치는 기본적으로 2 바이트의 16 비트 수량 분할입니다. Next (디스펜서의 다음 티켓과 같은)과 Owner (카운터를 통한 '지금 검색'번호와 같은)을 호출합시다. 스핀 록은 두 부분을 모두 0으로 초기화하여 초기화됩니다. 잠금은 스핀 록의 값을 메모하고 원자 적으로 다음을 증가시킵니다. 증가하기 전의 다음 값이 소유자와 같으면 잠금이 확보됩니다. 그렇지 않으면 소유자가 올바른 값으로 증가 할 때까지 회전합니다.

관련 코드는 asm/spinlock.h (x86의 경우)입니다. 잠금 해제 작업은 참으로 훨씬 빠르고 간단하게 책을 말한다보다 : inc 이후

static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) 
{ 
    asm volatile(UNLOCK_LOCK_PREFIX "incb %0" 
     : "+m" (lock->slock) 
     : 
     : "memory", "cc"); 
} 

약 8 또는 9 배 빠른 btr보다.

희망이 도움이됩니다. 그렇지 않다면 나는 더 깊게 파고 행복 할 것이다.