서버의 특정 부분에서 써보자는 얘기가 나와서 사실 관계랑 rein의 개인적인 견해를 정리.
Windows API에는 *nix 에서 user–level thread라고 부르기도하는 “fiber”에 대한 API가 존재한다. 사실 이 Fiber(섬유)란 단어 자체가 약간 말장난이기도한데[1], 크게 보면 다음과 같은 구성이 된다.[2]
Fiber는 ::ConverThreadToFiber, ::CreateFiber, ::DeleteFiber, ::SwitchToFiber 등의 API를 통해서 제어되는데, 그 시작, 종료 그리고 Fiber간의 context–switching을 사용자가 조절할 수 있다(스케쥴링)는 점에서 스레드랑 가장 차이가 난다. 물론 스레드 A에서 만든 fiber를 스레드 B에서 동작시켜도 되기 때문에 스케쥴링 할 때 스레드–fiber 소유관계를 확인해야하는 문제는 없다[4].
Windows 시스템 프로그래밍[5] 에서 소개하는 fiber의 용도는,
정도다. 일단 첫번째 유형이 내재된 목적인 것 같은데[7] 코루틴이나, 절대로 blocking되면 안되는 서버프로그램의 작업 스레드등에의 blocking-job 처리에는 쓰일 수 있을듯도 하다.[8] 덤으로 ::TerminateThread()가 아주 예외적인 경우를 제외하고는 쓰지 말아야하는 함수인 것과는 대조적으로 ::DeleteFiber()는 아주 안정적으로 동작할 수 있다 — 왜냐하면 특정 fiber가 실행될지 말지는 유저 관점에서 완벽히 알 수 있기 때문에.
장점이 있긴하지만 다음과 같은 문제는 좀 괴롭다.
커널에서 지원되는 스레드나 성숙된 유저 레벨 스레드 라이브러리가 편한(?) 것은 스케쥴링 문제가 직접 노출되어 있지 않기 때문이다. Fiber는 SwitchToFiber()를 호출해서 직접 실행시켜주기 전에는 돌지 않기 때문에 (thread는 언젠가는 OS가 CPU를 쓰게 해준다), 적절한 시점에 적절한 Fiber를 골라서 동작하게 만들어 줄 수 있다. 그리고 스케쥴링은 절대 쉬운 문제가 아니다 — 물론 잘만들면 성능 향상을 기대할 순 있다.
Fiber로 비동기 작업을 할 수 있긴 하지만(polling이나 fiber가 스케쥴링으로), scalable하진 않다. 비동기 작업 당 1개의 fiber가 필요해서 최대 비동기 작업 수를 알아내거나, 전통적인 비동기 작업 처리 방식들을 섞어써야한다 — 그리고 그럴 바엔 그냥 잘 정의된 멀티스레드 응용을 쓰는게 낫다.
Fiber는 OS관점에서 보이는게 아니기 때문에, 서로 다른 fiber가 동기화되려면 결국엔 fiber밑에 있는 스레드들을 동기화 시키는 수 밖에 없다. Mutex 같은 커널 객체에 락을 거는 주체는 thread지 fiber가 아니다.
뭐 이런 이유로 정말 필요한 상황 — 예를 들어 co–routine이 필요하다거나 — 이 아니면 멀티스레드 응용에서 fiber 사용은 권장할만한 일이 아니라고 생각한다.
한번에 한 파이버밖에 못 도니까 성능으로는 MT를 따라잡진 못할 거고, 따라서 ST 기법과 비교하자면, 여러 작업이 병렬적으로 수행되는 코드를 짤 때 수행의 연속성이 코드상에 드러난다는 게 파이버의 주요 장점일 듯.
그런데 코드 중간에 스위치해서 나가 버리면 역시 코드 짜기 짜증날 거라는 생각이 드네. 파이버와 MT를 섞어 쓰면 ‘락을 잡은 상태에서 나가면?’ 이런 문제도 있고. MT만큼 예측불허의 사건이 벌어지는 것은 아니지만, 코딩할 때 ST보다 더 많은 것을 머리에 올려놔야 할듯해.
(어제 저녁에 컨테이너 소멸중에 컨테이너 다시 건드리는재진입 문제로 고생했ㅎ)
사실 MT IOCP가 패킷을 뽑아다가 큐에 쏟아넣고 로직 스레드는 ST+파이버로 쓰는 구조를 고려해봤었는데 성능이 CPU 개수에 대해 스케일러블하지 않을듯해서 버렸음.
Written by Rica on February 21, 2008 at 1:43pm
그 scalable하지 않을 듯한 방법(로직 부분에 ST + fiber)을 쓰자는 사람이 있는데 조금만 더 생각해서 주장해줬으면 하는 소망이 있음;
직접 스케쥴링하는데서 뽑아낼 수 있는 이득이 없으면 fiber가 득보다 실이 클 것 같은데 말이지 -_-a
Written by rein on February 21, 2008 at 2:29pm
Jump to comments