스핀 락은 폴링과 어떻게 다릅니 까?


41

스핀 락과 폴링은 같은 것입니까?

위키 백과 :

spinlock은 잠금을 사용할 수 있는지 반복적으로 확인하면서 스레드를 획득하려고 시도하는 스레드가 단순히 루프 ( "스핀")에서 대기하도록하는 잠금입니다.

이것은 다음과 같이 끔찍하게 들립니다.

while(!ready);

나는 그것이 최적의 차선책 이었기 때문에 가능할 때마다 폴링을 피하도록 배웠다. 그렇다면 spinlock은 오래된 오래된 폴링의 멋진 이름입니까? 스핀 락은 폴링과 어떻게 다릅니 까?

답변:


85

폴링이란 리소스 ( 모든 종류의 리소스)가 준비 되었는지 반복적으로 확인하는 것을 말합니다 .

스핀 록은 폴링하는 리소스가 잠금 인 경우입니다.

그 폴링을 참고입니다 하지 나쁜. 특히 폴링은 일반적으로 폴링 할 때 데이터가 준비되어있을 때 효율적입니다. 폴링은 데이터를 반환하지 않고 수행하는 경우에만 비효율적입니다.

반면에 데이터가 너무 많아서 지속적으로 중단되는 경우 인터럽트는 비효율적입니다. 데이터가 거의 도착하지 않으면 효율적으로 작동하여 실제로 중단되기 전에 유용한 작업을 수행 할 수 있습니다.

15 년 전, 새로운 이메일이 올 때마다 나를 방해하도록 이메일 프로그램을 설정했습니다. 일주일에 한 두 번 일어났습니다. 내받은 편지함을 지속적으로 확인하는 것은 엄청난 시간 낭비였습니다.

요즘에는 모든 알림이 해제되어 있습니다. 받은 편지함을 볼 때마다 새로운 이메일이 도착한다는 것을 알고 있습니다. 폴링이 훨씬 더 효율적입니다.

스핀 락 잠금이 수행되는 것을 a) 가능성이 낮을 때 효율적이며, b) 경우에 잠금이 수행되며, 이는 짧은 시간 동안 유지된다. 다시 말해서 : 대부분 비경쟁 미세 입자 잠금에는 효율적이지만 고도로 집중된 굵은 자물쇠에는 비효율적입니다.

(물론, 스핀 락은 진정한 병렬 처리가 있어야만 작동합니다.


5
멀티 태스킹 환경에서 스핀 록을 완벽하게 감지 할 수 있습니다. 루프에서 제어권을 확보해야합니다.
케빈

4
이메일로 좋은 예입니다. 생각 나는 당신이 항상 이메일을 ...
페트르 Pudlák

2
@ 케빈 : 나는 스핀 락에 대한 매우 순수한 아이디어를 가지고 있습니다. 문자 그대로 빈 루프에서 회전하는 잠금 장치입니다. ( atomically_do { while (lock.is_locked?); lock.acquire! })이 산출되면, 따라서 빈 루프가 아니라 그 puristic 한보기에서 스핀 록이 아니다 - D 그러나 잠금 또는 이완 / 현실 세계에서 플라톤의 이상적인 메이크업의 완벽한 감각에 추가의 다른 유형 물론 일부 하이브리드.
Jörg W Mittag

3
@bubakazouba : 스핀 록은 빈 루프에서 문자 적으로 "회전"하고 "잠금이 해제 되었습니까? 아직 잠금이 해제 되었습니까? 잠금이 아직 해제 되었습니까? 잠금이 아직 해제 되었습니까? 아직 잠금이 해제 되었습니까?" 다시 반복하여. 병렬 처리가없는 경우 잠금을 해제 할 수있는 다른 스레드가 동시에 실행되지 않으므로 무한 루프가 효과적으로 발생합니다! 바로 위의 주석을 참조하십시오.
Jörg W Mittag 2011

1
@kasperd : nginx와 같은 이벤트 중심 서버 소프트웨어에서 협업 멀티 태스킹을 볼 수 있습니다. 이 경우 하나의 스레드와 잠금이 없으므로 하나의 코어 만 이용할 수 있습니다. 내가 아는 한, 진정한 멀티 코어 협업 멀티 태스킹의 실제 사례없습니다 . 이러한 시스템은 잠금이 없어도 협업 멀티 태스킹의 모든 단점을 갖기 때문에 어리석은 일입니다.
Kevin

10

spinlock은 잠금 유형으로, 특히 폴링 을 통해 달성 되는 잠금 유형입니다 .

폴링은 무언가의 상태를 확인하는 방법입니다 (상태를 기다리지 않고 상태를 묻음).

키보드 키의 상태를 폴링하는 것과 같이 모든 폴링이 스핀 락 인 것은 아닙니다.


또한 폴링은 본질적으로 나쁘지 않습니다. 매우 짧은 폴링 기간은 인터럽트 사용에 필요한 값 비싼 컨텍스트 전환을 피할 수 있습니다. 물론 폴링은 구현하기가 더 간단하고 특히 낮은 레벨에서 유지 관리가 더 쉬울 수 있습니다. 평소와 같이 절대 값은 끔찍한 것이며 옵션을 맹목적으로 사용하거나 버리지 않고 측정 할 때 필요에 따라 적절한 성능 / 복잡성 균형을 유지하는 방법을 사용해야합니다 .


5

스핀 록은 몇 밀리 초 이하 의 매우 짧은 시간 동안 만 발생하기 때문에 폴링과 다릅니다 . 폴링은 무기한 진행될 수 있습니다.

병렬 프로그래밍에서는 컨텍스트 전환 및 커널 전환 비용을 피하기 때문에 짧은 회전 에피소드가 차단보다 선호되는 경우가 많습니다.


C #에서 SpinLock 및 SpinWait에 대한 추가 읽기 Spinlocks 및 C에서
읽기 / 쓰기 잠금


나는 당신이 마이크로 초를 말하는 것을 의미한다고 생각합니다. 전체 밀리 초 동안 지속되는 잠금의 경우 경합에서 커널 호출을 수행하는 잠금 구현을 사용해야합니다.
피터

@Peter 아마도 그것은 Albahari의 의미 일 것입니다. 그것이 그의 텍스트가 말하는 것입니다.
Robert Harvey

4

차이점은 스핀 락은 (적절하게) 그것이 적절한 상황에서만 사용된다는 것인데,이 상황에서는 매우 효율적입니다.

리소스가 매우 짧은 시간 동안 만 잠길 것으로 예상되는 경우 스핀 락을 사용합니다 (예 : 잠금을 사용하여 변수를 업데이트하는 경우). spinlock은 최대 속도로 잠금을 폴링하지만, 마이크로 초 미만 동안 희망합니다. 정상적인 뮤텍스는 OS 호출에 필요합니다. 경우 잠금이 유일한 시간의 작은 양 개최 된 OS 호출이 오래 걸릴 수 있지만, 다음 스핀은, CPU 시간의 작은 금액을 사용합니다. 그러나이 기대가 잘못되면 스핀 락은 매우 비효율적입니다. 하나의 CPU에서 100 % CPU 시간을 사용하는 반면 일반 뮤텍스는 OS에 들어가서 돌아 오는 데 시간이 걸립니다.

때로는 둘 다 결합됩니다. 스핀 락을 잠시 동안 실행하고 스핀 락이 작동하지 않으면 다른 전략으로 전환하십시오.


2

과도한 폴링은 시스템 리소스를 낭비하기 때문에 수행하지 말아야합니다. 이 것을 다음 은 시스템 자원을 낭비하지 않는 경우 폴링이 괜찮습니다 .

예를 들어 실제 작업으로 인해 2 % 만로드되는 경우 과도한 폴링은 CPU로드를 100 %로 가져옵니다.

폴링은 이외의 다른 용도로 사용될 수 있습니다 while(!ready). 예를 들어 사용자가 키를 눌렀는지 정기적으로 확인하는 것을 의미합니다. 정상적인 구현은 15 밀리 초마다 최대 한 번만 확인하므로 ~ 2 천만 클럭 사이클마다 한 번만 확인됩니다. 이러한 종류의 폴링은 시스템 리소스를 낭비하지 않기 때문에 훌륭합니다.

SpinLock은 특별한 경우 가 아닙니다 . SpinLock이 있고 하나의 스레드가 잠금에 들어가고 다른 스레드가 대기해야하는 경우 대기중인 스레드가 시스템 자원을 낭비하는 경우에만 SpinLock이 잘못 선택됩니다. 대기 스레드는 잠금을 획득하기 전에 상당한 시간을 기다려야하는 경우에만 시스템 자원을 낭비합니다.

따라서 SpinLock을 사용하여 다시 잠금을 해제하기 전에 수천 클럭 사이클 이상이 필요한 것을 보호하기 위해 (예 : 자바 스크립트를 컴파일하고 실행하는 것) 잘못된 이유는 바로 그 이유입니다. 그러나 대기 스레드가 2 ~ 3 회만 회전하므로 시스템 리소스를 낭비하지 않기 때문에 올바르게 구현 된 해시 맵에 액세스하는 것과 같이 SpinLock을 사용하여 빠르게 완료되는 항목을 보호하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.