화창한 봄날 남들은 연인끼리 벚꽃 놀이에 가는데 저는 회사에서 일을 하고 있습니다. ㅠㅠ;
이왕 나온거 머라도 하나 건져가야 되지 않겠냐는 생각에 어제 스터디에서 마지막에 화두가 되었던
유니프로세서에서의 spinlock에 대해 곰곰히 생각을 하다가 놀라운 사실?을 발견하게 되었습니다.
먼저 결론부터 말씀 드리면 유니프로세서에서 스핀락이 preemption disable로 조건부 컴파일 되는것이 아니라
아예 흔적조차 없이 사라진다는 것입니다. 왜냐? spinlock 이라는 매커니즘 자체가 처음부터 SMP에서의 동기화를
위해 만들어 졌기 때문에 유니프로세서에서는 전혀 필요가 없는 것이지요.
이러한 결론에 도달하기 위해서 IQ120의 짱구를 열심히 굴려 댔습니다.ㅋ
자 그럼 과정에대해 말씀 드리겠습니다.
"락을 얻기 이전에 반드시 로컬 인터럽트 (현재 프로세서의 인터럽트 요청)를 비활성화 해야 한다. 이하 생략..." (P.138)
저는 이 문장에서 난관에 봉착합니다. 인터럽트 컨텍스트와 프로세스 컨텍스트간의 임계영역을 동기화 하기 위해서
"인터럽트를 비활성화하고 락을 얻는다."라고 했는데 인터럽트만 비활성화 해도 동기화가 가능해 지는데 왜 락을
얻어야 되는가? 인터럽트 컨텍스트와 프로세스 컨텍스트간에 임계영역이 존재 할 경우 프로세스 컨텍스트에서 임계영역에
진입하기 전에 인터럽트를 비활성화 하고 임계영역을 빠져나올때 인터럽트를 다시 활성화 하는 것만으로도 동기화가
달성되기 때문입니다. 이 의문이 해결되지 않아 고민을 하던 중 저는 책에서 다음과 같은 내용을 발견 하게 됩니다.
"다른 프로세서에서 인터럽트가 발생 할 경우, 그것이 같은 락을 대기한다고 하더라도 락을 가진 코드를 방해하지 않으므로.
이하 생략..." (P.138) 즉! 임계영역을 공유하는 인터럽트가 프로세스 컨텍스트에서 임계영역에 들어가 작업을 수행 중인
프로세서가 아닌 다른 프로세서에서 동시에 처리 될 수 있기 때문에 락을 얻어야 하는 것입니다. 여기까지 이해하자마자
유니프로세서에서 스핀락이 완전히 사라져 버렸습니다.ㅋ
정리하자면 유니프로세서에서 인터럽트 컨텍스트와 프로세스 컨텍스트간의 임계영역을 동기화 하기 위해 스핀락은 전혀
필요 없습니다. 단지 로컬 인터럽트를 비활성화 하고 활성화 하는 것만으로 동기화가 달성 되는것이지요.
스핀락은 처음부터 SMP에서의 동기화를 위해 사용된 것입니다.
그러면 이러한 의문이 기다고 있습니다. 유니프로세서에서도 컨텍스트 스위칭에 대비해 임계영역에 스핀락을 사용해야 하는것이
아니냐? 네 충분히 가능한 질문이고 충분히 사용 가능합니다. 하지만 이를 위해 스핀락을 쓰지 않는다는 것이지요. 왜냐?
스핀락은 애시당초 SMP에서의 동기화를 위해 만들어진 것이기 때문입니다. 그럼 유니프로세서에서는 컨텍스트 스위칭에 대비해
임계영역을 어떻게 보호하냐? 이는 애시당초 스핀락이 아닌 preemption disable이나 세마포어 등등으로 보호되게 설계된
것입니다.
그러므로 유니프로세서 옵션으로 커널 컴파일 시에 스핀락이 완전하게 말끔히 사라지게 되고 사라져도 안전한 것입니다.
끝으로 OT 때 백창우님께서 하신 말씀이 생각 나서 적어봅니다. ^^;
"아이구! 왜 이걸 이제야 알게 되었을까? 이럴 줄 알았으면 진작에 스터디를 할걸!!!"
잘못된 내용과 이해되지 않는 내용이 있으면 댓글 부탁 드립니다.
댓글 8
-
박한범
2011.04.18 09:58
-
홍문화
2011.04.18 10:47
네 맞는 말씀 입니다. ^^;
커널에서 제공하는 함수는 동일한 인터페이스를 제공 할 뿐이지 실제 어떻게 락을 걸어 코어 간에 동기화를 달성
하느냐는 아키텍처(cpu 벤더)마다 다르게 구현 되겠죠. 그래서 커널 책을 본 뒤에 arm 책을 보기로 한거구요. ㅋ
-
홍문화
2011.04.18 14:43
악!!!
오늘 다시 다음 장을 넘겼는데 "락 메커니즘은 컴파일시 제거된다. 락과 언락은 각각 커널 선점을
비활성화/활성화 한다." (P.139)
무엇을 상상하든 확실한건 코드를 분석해봐야 알게 되겠네요. ㅋㅋ
-
홍문화
2011.04.19 11:15
와우!!! 감사합니다. ^^;
안그래도 임계영역을 공유하는 인터럽트 컨텍스트 하나, 프로세스 컨텍스트 두개가 있는 경우에
프로세스 컨텍스트간에 동기화가 어떻게 이루어 져야 하나에 대해 고민 하던 참이었습니다.
인터럽트 컨텍스트와 프로세스 컨텍스트간의 동기화는 임계영역을 공유하는 인터럽트만을 디스에이블
한다고 이해를 하고 있어서 그러면 프로세스 컨텍스트간의 동기화는 스핀락의 몫이 되는게 아닌가? 하며
짱구를 굴리고 있었는데 해당 프로세서의 모든 인터럽트를 금지 해버리니 화끈하게 이해가 되네요. ㅋㅋㅋ
그런데 아쉬운게 SMP에서는 해당 프로세서의 인터럽트를 모두 금지 해버려도 다른 프로세서가 처리를
할 수 있으니 상관 없을거 같은데 UP에서는 미미하나마 성능 저하가 발생 할 수 있겠네요.
-
김윤기
2011.04.18 23:24
이말은 즉 spin_lock_irqsave와 spin_lock_irqstore에 적용되는것 같습니다. 여기서 단일프로세서의 경우 요부분이 통째로 사라지는것이 아니고 그안에 구현되어 있는 락 메커니즘만 사라지는것을 뜻하는것 같네요 제 습자지 같은 견해로서는 어짜피 로컬 인터럽트를 금지해 버리면 커널은 선점이 되지 않거든요. 왜냐하면 커널을 선점하는 코드 (즉 스케쥴링에 관여한 코드)도 타이머 인터럽트를 기반으로 돌아갈테니깐 로컬 인터럽트를 금지시켜버리면 선점이고 뭐고도 동작하지 않는다고 생각되거든요 ㅎ 맞나요..? T_T
그래서 단일프로세서의 경우 lock/unlock의 관련한 코드는 쓰잘때기 없는 중복된 코드가 되는 것이죠 즉 spin_lock_irqsave와 spin_lock_irqstore의 역할은 단지 local_irq_save/local_irq_restore와 같은 역할로 돌아가는것이 아닐까 합니다. 더 자세한건 아래분이 설명해드릴꺼에요 ㅋㅋ 지식이 습자지인자 ㅋㅋㅋ 그럼 즐커공하세요 ㅎ
-
김윤기
2011.04.18 22:16
흠 글쿤요~~~ 저는 오늘 예비군 갔다 왔습니다 추워 죽는줄 알았어요~~ 이로서 저의 마지막 예비군은 바이바이 ㅎ
-
myskan
2011.04.19 13:35
운영체제 내부 구조 및 설계 원리에 Linux 커널의 병행기법을 살펴 보다가 다음과 같은 문구를 찾아서 공유합니다.
-> 스핀 락의 실제 구현은 단일처리기 시스템에서와 다중처리기 시스템에서 약간 다르다. 단일 처리기 시스템의 경우에는 우선 커널이 선점 가능 상태인지 고려한다. 만일 선점 가능하지 않다면, 쓰레드가 커널 수준에서 수행될 때 간섭받지 않는다는 의미가 되고, 결국 락은 불필요하게 된다. 따라서 이 경우에는 컴파일 단계에서 락이 삭제된다. 반면에, 선점 가능한 상태라면, 단일처리기에서는 인터럽트 금지와 허용을 스핀 락의 획득과 반납으로 사용할 수 있다.
남겨 놓으신 글을 보고 OS에 대해 많은 지식이 없어 nested 인터럽트 및 세마포어에 관하여 상상의 나래를 펼치면서 관련 자료를 찾다가 발견하게 되었습니다. ^^;
p.s IQ120 이면 영재 수준 아닌가요? ??
-
홍문화
2011.04.19 13:59
이제 UP든 SMP든 스핀락의 기초를 정복한거 같습니다. ㅋㅋ
우리나라 국민 평균 IQ가 106 이라고 하네요.
일단 평균을 넘었으니 먼저 부모님께 감사드립니다. ㅋㅋ ^^;
.
흐흠!!
그렇군요. 저는 위의 내용은 생각해보지 않아서 모르겠습니다.
spinlock 의 특징이라고 할만한 사항은 두 가지인데 하나는 spin이고 하나는 말씀하신 smp(이게 뭔지도 잘 모르겠습니다.) 의 동기화겠죠? spin 자체는 그다지 어려운 개념도 아니구요. 그냥 락을 얻을때까지 루프하는 거니까...
한가지, 제가 궁금해서 찾아본 건데요. smp 에서 락을 어떻게 거냐는 겁니다.
예를 들어, 멀티쓰레드와 마찬가지로 동기화의 문제가 생기는데 이게 코어급에서 발생하면 cpu단이므로
어떻게 커널에서 제어할 수가 없단 말이죠. -_-;;
이 부분은 커널에서 제어할 수 없어서 cpu 벤더가 제공해준 기능을 사용합니다.
원자연산이라고 말씀드리면 대충 눈치 채실듯 하구요.
원자연산시에 cpu에는 두 가지 종류의 락이 걸리는 걸로 알고 있습니다.
하나는 캐쉬락이고, 다른 하나는 메모리 버스에 대한 락입니다.
보다 정확한 정보는 아랫분이 주실것 같군요. 전 허접한 실력 드러나기전에 도망가야겠습니다. ㅌㅌ...