ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • IOCP(1)
    개발/C·C++ 2021. 5. 25. 20:51

    >> 번역글입니다

    >> 의역은 있고 오역이 있을 수 있습니다

    >> 출처 https://docs.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports

     

    I/O Completion Ports

    입출력 완료 포트는 멀티프로세서 시스템에서 여러가지 비동기 입출력 요청을 처리하는 효율적인 스레딩 모델입니다. 프로세스가 입출력 완료 포트를 만들면 시스템은 요청을 서비스하기 위해 연관된 큐 객체를 생성합니다. 동시적인 비동기 입출력 요청을 처리하는 프로세스는 요청이 있을 때 스레드를 만들지 않고, 미리 할당된 스레드풀과 입출력 완료 포트를 통해 더 빠르고 효율적으로 일할 수 있습니다.

     

    How I/O Completion Ports Work

    CreateCompletionPort 함수는 입출력 완료 포트를 만들며 하나 혹은 그 이상의 파일 핸들을 포트에 연결합니다. 파일 핸들 중 하나의 비동기 입출력 동작이 완료되면, 입출력 완료 패킷은 연관된 입출력 완료 포트에 FIFO(first-in-first-out) 순서로 대기합니다. 다른 많은 유용한 애플리케이션이 있지만, 이 메커니즘은 한 가지 객체에 여러가지 파일 핸들에 대한 동기 지점을 조합하는 것에 쓰일 수 있습니다. 패킷은 FIFO 순서로 대기행렬에 쌓이는 반면, 빠질 때는 다른 순서일 수 있다는 것을 알고 있어야 합니다.

     

    Note
    여기에 사용된 파일 핸들이라는 용어는 디스크에 있는 파일 뿐만 아니라 중첩된 입출력 종단(overlapped I/O endpoint)을 표현하는 시스템 추상을 가리킵니다. 예를 들어 네트워크 종단, TCP 소켓, 이름 있는 파이프 혹은 메일 슬롯이 될 수도 있습니다. 중첩 입출력(overlapped I/O)를 지원하는 시스템 객체라면 사용될 수 있습니다.

     

    파일 핸들이 완료 포트와 연결되어 있을 때, 전달된 상태 블록은 패킷이 완료 포트에서 제거되기 전까지 갱신되지 않을 겁니다. 유일한 예외는 기존의 동작이 에러와 함께 동기적으로 반환될 때입니다. (메인 스레드가 만들었거나 메인 스레드 그 자체이거나) 스레드는 비동기 입출력이 끝나기를 직접 기다리지 않고, GetQueuedCompletionStatus 함수를 사용해 입출력 완료 포트에서 줄 서고 있는 패킷들을 기다립니다. 입출력 완료 포트에서 실행이 막혀있던 스레드는 LIFO(last-in-first-out) 순서로 해제되며 해당 스레드에 대해, 다음으로 완료된 패킷은 입출력 완료 포트의 FIFO 큐에서 가져옵니다. 이 프로세스가 의미하는 바는 완료 패킷이 스레드에 방출될 때, 시스템은 가장 오래된 입출력 완료 정보를(FIFO이므로 처음 들어온 것이 가장 오래된 정보) 스레드에 전달하며 해당 스레드는 포트와 관련있는 가장 마지막(가장 최근) 스레드입니다(LIFO이기 때문에, 마지막이 최근).

    개인적의 의견
    입출력 완료 포트가 큐인 이유는 완료된 핸들을 순차적으로 처리하는 게 빠르기 때문이고, 가장 최근 스레드가 자주 쓰이는 이유는 캐시의 시간 지역성의 개념과 비슷한 것 같습니다. 가장 최근에 사용된 스레드를 사용하는 것(메모리에 접근하는 것)이 컨텍스트 스위칭에 대한 오버헤드가 가장 적기 때문이지 않을까요.

     

    스레드는 특정 입출력 완료 포트에 대해 GetQueuedCompletionStatus를 호출할 수 있지만, 특정 스레드가 GetQueuedCompletionStatus를 처음으로 호출하면, 다음 세 가지 중 한 가지라도 발생하기 전까지는 특정 입출력 완료 포트와 연결되어 있습니다. 스레드가 종료되거나, 다른 입출력 완료 포트를 특정하거나, 입출력 완료 포트를 닫는 경우. 달리 말하면 하나의 스레드는 기껏해야 하나의 입출력 완료 포트와 연결될 수 있습니다.

     

    완료 패킷이 입출력 완료 포트에 순차적으로 들어갈 때, 시스템은 가장 먼저 포트와 연결되어 작동하고 있는 스레드가 얼마나 많은지를 검사합니다. 작동하고 있는 스레드의 수가 동시 실행 변수(concurrency value, 다음 섹션에서 논의됨)보다 작으면 대기하고 있던 스레드 중 하나(가장 최근 것)가 완료 패킷을 처리하도록 합니다. 동작 중인 스레드가 처리를 완료하면 일반적으로 GetQueuedCompletionStatus를 다시 호출해 다음 완료 패킷을 반환하거나 큐가 비어 있으면 대기합니다.

     

    >> IOCP(2)로 이어집니다.

    '개발 > C·C++' 카테고리의 다른 글

    [Design Pattern] Observer  (0) 2021.05.30
    [Pointer] 정수형을 문자형으로  (0) 2021.05.28
    [Rvalue reference] Rvalue Reference(3)  (0) 2021.05.21
    [Rvalue reference] Move Semantics(2)  (0) 2021.05.12
    [Rvalue reference] Introduction(1)  (0) 2021.05.12

    댓글

Designed by Tistory.