앞서 정리했던 스트림과 늘 붙어다니는 개념이 바로 버퍼(Buffer)다.
버퍼도 스트림과 같이 일상에서 자주 쓰이는 용어다.
누구나 한번쯤 영상을 보다가 멈추면 "버퍼링에 걸렸다"라고 말해본 경험이 있다.
여기서 말하는 버퍼링이 버퍼의 동작을 일컫는 말이다.
스트림과 마찬가지로 버퍼라는 용어는 여러 영역에서 다양하게 적용되어 사용된다. 하지만 큰 맥락은 비슷하기 때문에 스트림을 정리하는 참에 버퍼까지 정리해두면 이후에 공부를 할때 도움이 될 것 같아 정리해두기로 했다.
1. 버퍼(Buffer)란?
우선 영단어 Buffer의 뜻을 알아보면,
Buffer
명사 1. 완충제 2. 완충 장치
동사 1. 완화하다 2. ~를 보호하다
완충 장치라는 말만 보고선 쉽게 버퍼의 뜻을 이해하기는 어렵다. 하지만 버퍼의 사용 목적은 무엇인가를 완화하는 것이겠구나 정도를 예측할 순 있다.
다음으로 정보통신용어사전을 통해서 Buffer를 검색해보면
Buffer
: 하나의 장치에서 다른 장치로 데이터를 전송할 경우에 양자간의 데이터의 전송 속도나 처리 속도의 차를 보상하여 양호하게 결합할 목적으로 사용하는 기억영역.
결국 버퍼는 두개의 장치 사이에서 데이터 전송할 때 데이터의 전송 속도나 처리 속도의 차이를 완화하는 목적으로 사용하는 기억장치인 것이다.
2. 버퍼(Buffer)의 동작
위에서 길게 정리한 버퍼를 쉽게 말하면, 임시 저장 공간이라는 것이다.
비디오 스트리밍에서 버퍼의 동작을 통해 버퍼의 동작을 쉽게 정리해보자.
앞서 정리해놓은 스트림에 대한 게시물에서 설명했듯이,
영상 스트리밍이란 서버에서 영상파일을 여러 조각으로 쪼개 연속적으로 데이터를 보내는 것을 말한다. 여기서 버퍼는 서버로부터 보내지는 영상 파일 데이터들을 순서대로 차곡차곡 쌓는 임시 데이터 공간인 것이다. 그림에서 볼 수 있듯이, 동영상을 볼 때 밑에 재생바에 짙은 회색으로 표시된 그 부분이 버퍼를 나타낸다.
즉 앞선 게시물과 연결해보자면, 영상 스트리밍이란 사용자가 영상을 클릭한 순간 서버로부터 여러 조각으로 나눠진 영상 파일들이 순서대로 버퍼에 쌓이기 시작하며, 쌓여진 데이터만큼 사용자는 시청을 할 수 있으므로 사용자는 영상을 클릭과 동시에 시청할 수 있고 계속해서 버퍼에는 데이터는 계속 쌓이기 때문에 사용자는 끊김 없이 영상을 시청할 수 있는 것이다.
영상 스트리밍 서비스에서 버퍼의 역할은 서버에서부터 들어오는 영상 파일 데이터들을 차곡차곡 임시 공간에 쌓았다가, 사용자가 시청할 수 있는 최소한의 크기가 만들어지면 그걸 화면에 뿌려질 수 있도록 출력 장치에 순차적으로 전달하여 사용자로 하여금 영상을 빠르게 볼 수 있도록 만들어주는 것이다.
다음으로는 입출력에서의 버퍼 동작을 통해 버퍼에 대해 좀 더 이해해보자.
우선 버퍼를 사용하지 않는 입력일 경우에 대한 그림이다.
예를 들어 사용자가 프로그램 사용 중 키보드를 통해 MOVE라는 단어를 쳤다고 가정해보자. 버퍼가 없는 경우에는 키보드에서 M, O, V, E를 각각 칠때마다 프로그램으로 해당 입력이 전달된다. 이 때 프로그램 내에서 작업과정을 들여다보자. 저 진한 파란 네모칸이 프로그램의 하나의 작업이고 네모의 크기가 한번에 처리할 수 있는 작업량이라고 가정한다. 버퍼를 이용하지 않는 경우에는 사용자가 키보드를 한번씩 클릭할때마다 각각의 문자가 프로그램으로 바로 전달이 되므로 문자마다 각각 하나의 작업으로 잡히게 된다. 이때 일반적으로 프로그램이 한번의 처리할 수 있는 작업량보다 입력된 하나의 문자를 처리하는 작업량의 크기는 매우 작다. 그러므로 매 작업마다 파란색 네모에서 보라색 네모만큼을 제외한 나머지 만큼의 작업량이 기회비용이 되어 날아가버린다. 결국 속도면이나 효율성 측면에서 떨어진다는 것을 알 수 있다.
다음으로는 버퍼를 사용할 때의 입력이다.
앞선 예시와 똑같이 사용자가 프로그램 사용 중 키보드를 통해 MOVE라는 단어를 쳤다고 가정해보자. 버퍼가 있는 경우에는 특정 문자나 행동이 들어올때까지(예를 들면 엔터나 스페이스 또는 버튼 클릭 등의 이벤트 등) 버퍼에 사용자가 입력한 문자 M,O,V, E를 차례대로 저장한다. 그러다 엔터나 스페이스와 같은 버퍼의 끝을 알리는 동작이 입력이 되면 지금까지 버퍼에 저장해두었던 문자를 프로그램으로 보낸다. 이때 앞선 예시와 같이 저 진한 파란 네모칸이 프로그램의 하나의 작업이고 네모의 크기가 한번에 처리할 수 있는 작업량이라고 가정한다면, 프로그램에서는 버퍼를 통해 들어온 "MOVE"라는 문자 처리를 하나의 작업으로 잡게된다. "MOVE"라는 단어도 일반적으로 프로그램이 한번에 처리할 수 있는 작업량에 비하면 매우 작지만, 대신 사용자가 입력한 문자 전체를 한번에 처리하므로 날라가는 기회비용이 적다. 결국 속도면에서나 효율적인 측면에서 버퍼를 사용하는 것이 좋다는 것을 알 수 있다.
이렇게 두개의 예시를 통해서 알 수 있는 중요한 점은 버퍼의 목적은 두 장치간에 전송 속도나 처리 속도의 차이를 완화하는 것이다. 첫번째 영상 스트리밍 예시에서 버퍼의 목적은 서버와 내 컴퓨터 사이에서 영상이 출력될 때까지의 시간을 완화하는 것으로 보면 된다. 두번째 입출력 예시에서 버퍼의 목적은 키보드(입력장치)와 프로그램 사이에서 처리 속도의 차이를 완화하는 것이다. 만약 버퍼가 없었다면 영상이 모두 다운받아질때까지 사용자는 기다려야할 것이며, 프로그램에서 입력이 길어질수록 프로그램의 속도는 저하될 것이다.
결국 버퍼란 처리 속도 차이가 나는 두개의 장치 사이에서 두 장치의 속도 차이를 완화하기 위한 것이다. 처리 속도가 느린 장치에서 처리 속도가 빠른 장치로 이동할 때에는(처리 속도가 빠르다는 것은 결국 한번에 처리할 수 있는 양이 많다는 것과 같다) 버퍼에 빠른 장치가 처리할 수 있는 만큼 모았다가 전달하여 효율적으로 데이터를 처리하게 하며 반대의 경우에는 데이터를 잘게 쪼개 처리한 뒤 버퍼에 모은 식으로 하여 두 장치를 효율적으로 연결하는 것이다.
그리고 추가적으로 버퍼는 임시 저장 공간이라 했는데, 임시 저장 공간이라는 것은 데이터를 저장하지 않고 휘발된다는 것을 뜻한다. 결국, 버퍼는 데이터들을 전달하는 바구니라고 생각하면 될 것 같다.