LISTORY

[윈도우즈 시스템 프로그래밍] 비동기 I/O의 이해 본문

IT/윈도우 프로그래밍

[윈도우즈 시스템 프로그래밍] 비동기 I/O의 이해

LiStoryTeller 2018. 11. 18. 16:23


뇌를 자극하는 윈도우즈 시스템 프로그래밍 책 관련 유투브 강의 정리이다.


저번 시간에 이어 비동기 I/O에 대해 정리를 계속하겠다.


YouTube 주소 : 비동기 I/O의 이해



비동기 I/O의 이해


우리가 이제껏 다룬 내용은 전부 동기 I/O이다.


동기 I/O?


write라는 함수가 있다. 이는 데이터를 보내는 함수이다.


이 함수를 호출하는 순간 데이터의 전송이 시작된다.


wirte 함수가 끝나는 순간은 데이터 전송이 끝나는 순간이다.


즉, 함수의 호출과 데이터 전송이 동기화, 함수의 반환과 전송의 끝이 동기화 되어있다.


이게 바로 동기화 I/O이다.


그럼 비동기는 무엇일까



⊙ 비동기 I/O?


wirte 함수를 호출하여 데이터 전송이 시작하는 것 까지는 똑같다.


하지만 함수를 반환하는 시점이 데이터 전송의 끝임을 의미하지는 않는다.


비동기 I/O는 wirte 함수를 호출하자마자 반환을 해버리고 내부적으로 슬슬 데이터 전송을 해나간다.



⊙ 비동기 I/O의 장점


예를 들어 보자. wirte 함수가 동기화되어있다는 것은 데이터 전송이 끝날때 까지 함수 반환을 안한다는 것이다.


그럼 그 동안 CPU는 할일이 있음에도 불구하고 할 수 없다.


비동기의 경우 write 함수를 호출하자마자 반환 되었으므로 또 다른 일을 할 수 있다.


여기서 질문이 있다. I/O연산이 계속되고 있는데 다른 일을 계속 할 수 있나?


답은 가능하다. I/O는 I/O 자체적으로 독립된 연산이다. 


우리가 파이프라인을 구성할 수 있는 이유는 ALU가 연산하고 있을 때 다른 일을 할 수 있기 때문이었다.


I/O와 CPU는 일이 나누어져 있기 때문에 의존도가 높지 않다.


즉, I/O 연산 중이어도 다른 일은 얼마든지 가능하다.



동기 I/O와 비동기 I/O에 대한 CPU 사용 내용을 보자.



위에 모델을 보면 CPU 사용률이 엄청 높다 떨어졌다를 반복한다. 떨어질 때는 CPU가 쉬고있다는 뜻이다.


이의 문제점은  CPU를 원활히 사용하지 못하는 프로그램이라는 것이다. CPU가 블러킹된 상태이다.


일을 시키지 않기 때문에 CPU도 이렇게 블러킹이 될 수 있다. 


밑의 그림은 CPU 사용률이 물결친다. 이는 CPU가 계속적으로 일을 하고 있다는 뜻이다.


일반적인 프로그램의 60% 이상이 I/O에 관련된 연산이다.


즉, 이렇게 CPU가 무리도 안가게끔 여유를 두고 CPU를 지속적으로 사용하고 있다는 것은 


CPU가 일할 수 있는 적절한 양을 시키면서 I/O 연산도 진행하고 있다는 것이다.


비동기 I/O 입출력을 사용할 경우 아래와 같은 CPU 사용 내역을 볼 수  있다.


보통 위에 모델이 더 구현하기는 쉽다. 


보편적으로 아래 모델이 더 좋은 모델이라 하지만, 경우에 따라선 위에 모델을 사용할 수 있다.



비동기 I/O의 종류


윈도우즈에서 제공해주는 대표적이고 일반적인 I/O 모델 두가지를 소개하겠다.


1. 중첩(Overlapped) I/O 

2. 완료루틴(Completion Routine) 기반 확장 I/O 



중첩(Overlapped) I/O 


단순히  I/O연산이 중첩되었다는 것을 뜻한다.



read 함수가 호출되었을 때 데이터 수신이 시작된다고 가정하겠다.


근데 사진을 보면 데이터 수신이 끝나기 전에 새로운 데이터 수신이 이루어지고 있다. 


이 말은 read함수 호출이 끝나자마자 새로운 read 함수를 호출했다는 것이다.


총 4개의  I/O작업이 중첩되어 있다. 이는 상당한 도움이 된다.



A, B, C가 통신을 한다. A-B, A-C가 동시에 통신을 하면 A가 느려질까?


그렇지 않다. 보편적으로  I/O는 느리기 때문에 CPU는 상대적으로 많이 기다린다.


그렇기 때문에 하나를 기다리던 두개를 기다리던 여러개 기다려도 상관이 없다.


이왕 1개를 기다리는 시간에 2개를 기다리는 것이 낫다는 것이다.



하지만 여기서 문제가 있다 보편적으로 각각이 I/O 작업을 할 때,  I/O가 완료가 되면 하다못해 파일에라가도 저장을 해야한다.


즉,  I/O연산이 끝나면 그에 대한 부가적인 작업이 있다는 것이다.


 I/O 연산이 끝나면 어떤 것의 연산이 끝났는지 확인을 해야한다는 것이다.


이는 비동기이므로 상당한 부담이 될 것이다.


각기  I/O 에 따른 부가적인 작업이 다르고 이를 구분하기 너무 어렵다는 것이다.


이 문제를 해결하기 위해 나온 것이 완료루틴 기반 확장 I/O이다.



완료루틴 기반 확장 I/O



뭐가 가능하냐


A I/O B I/O C I/O가 끝났을 때 각각 실행되어야 하는 루틴...  이는 함수 호출을 의미한다.


이를 자동적으로 묶어 두는 것이다.


연산이 끝났을 때 그에 대한 부가작업, 즉, 어떤게 끝났는지 확인하는 일에 대한 부담을 덜어줄 수 있다.


윈도우즈에서 가장 대표적이며 일반적인 두가지  I/O 모델이다.




Comments