출처: http://developer.cybozu.co.jp/archives/kazuho/2009/12/tcp-064e.html

TCP 통신을 하는 프로그램을 만들 때 "데이터 전송은 모아서 1회'로 해야 한다는 것은 철칙이라고 말해도 좋다고 생각한다. 이유는 패킷 수를 최소화 하는 것으로 오버 헤드를 줄일 수 있기 때문이라고 일반적으로 설명하지만, 나는 또 다른 포인트가 있다고 생각한다.

아래의 그래프를 보자.

그래프는 일정량의 데이터를 전송하는데 걸리는 시간과 사용하는 블록 크기(1회 write(2)로 쓰기 크기)의 관계를 나타낸 것이다 (주 1).

호스트 간의 TCP 통신을 수행하는 경우는 TCP 버퍼가 유효하게 기능하기 때문에 블록 크기 (= 패킷 수의 역수)에 의한 속도의 변화는 거의 없다. 한편, 동일한 호스트에서 통신을 하면 블록 크기와 반비례하여 시간이 반비례 관계에 있음을 알 수 있다.

원인은 동일한 호스트의 통신에서는 전송 프로세스가 write(2)를 호출 할 때마다 컨텍스트 스위치가 발생하고 수신 프로세스가 깨어나서 read(2)로 데이터를 수신하기 때문이다.

이 오버 헤드가 크기 때문에 블록 크기를 줄이는데 반비례하여 속도가 느려지는 것이다.

이러한 경향은 송수신 프로세스가 교대로 시작하는 단일 프로세서 시스템 뿐만 아니라 별도의 CPU에서 실행되는 멀티 코어 환경에서도 마찬가지이다.

이상이 TCP 통신을 하는 프로그램은 데이터의 전송을 모아서 1회 실시 해야 하는 또 하나의 이유이다. 애플리케이션 프로그래머의 관점에서 보면, 호스트 간의 TCP 통신은 처리량을 중시하지만, 동일한 호스트 사이의 통신은 지연을 중시한다고 이해 해 두면 좋을 것이다.

적어도 빠른 서버 프로그램을 개발할 때 로컬 및 원격으로 벤치 마크를 하면서 튜닝을 해야 확실하다고 생각한다.

내가 어제 Shibuya.pm #12에서 "서버 프로그램은 원격 호스트에서 벤치마킹 해야 한다주 2"라고 주장한 것은 위의 것을 토대로 한 것으로 불필요한 컨텍스트 스위치를 피해야 한다는 생각에서이다. 지금 수중에 좋은 데이터가 없지만, 서버 및 벤치 마크 프로그램 양자를 동일한 호스트에서 움직였을 경우에만 컨텍스트 스위치가 빈발하여 성능이 저하하는 경우가 있었다고 기억하고 있다 (주 3).

 

서버 제작은 제품에 따라 다르기 때문에, 최대 처리량을 비교하는 벤치 마크 테스트를 할 경우 원격 호스트에서 측정하는 것이 공정할 것이다.

주 1 : 확실히 linux 2.6.18에서 측정. TCP_NODELAY는 set 되어 있다.

주 2 : "실제 이용 형태가 원격 호스트에서 액세스 될 수 있다면"라고 해야 할지도

주 3 : 예를 들어 멀티 스레드 서버와 멀티 스레드 클라이언트 라면 속도가 떨어진다고 생각한다.

주 4 : 최대 처리량을 필요로 하는 대규모 작업은 보통 원격 호스트 서버를 이용한다고 생각할 수 있기 때문에