모바일 환경에서도 온라인 게임을 즐길 수 있는 이유

■ 상황 요약
게임을 플레이할 때 거의 무선 통신을 이용해서 게임을 한다. 스마트폰으로 WiFi 나 LTE 혹은 간혹 3G 통신을 쓰기도 하고, PC나 랩탑으로 게임을 할 때도 굳이 유선 랜을 쓰는게 선 없이 아니라 WiFi를 쓰기도 한다.

무선 통신으로 보내는 메시지는 얼마나 잘 깨질까?

1
▲ 출처 : https://xkcd.com/654/

  1. 여보세요. 메건 찾아? 걔 게임 중이야 / 알아. 근데 나초가 참 맛있는데.
  2. 나초 칩 위에 모두 치즈를 얹고, 쑤어 크림이랑 살사에 빠뜨리면…
  3. 으음 그거 맛있지. 재료도 다 있네. / 만들어 봐! / 그럴께 / 어서!
  4. (전자렌지 돌아가는 소리)
  5. 내 WiFi!
  6. (쾅) 헤드샷.

조금 과장되긴 했지만, 전자렌지를 쓰면 흔히 2.4 GHz 대역을 쓰는 WiFi 신호에 악영향을 준다. (사실 이건 WiFi가 쓰는 ISM 대역은 전자렌지가 방출하는 신호 때문에 간섭이 커서, 다른 용도로 할당하기 어려워서 특정 기준만 만족하면 아무나 쓸 수 있는 대역이라 그런 것이다.)


■ 문제
무선 환경 자체가 어떤 문제를 주는가? 물리적인 문제와 게임에서 흔히 쓰는 TCP 프로토콜 자체의 문제를 확인해보겠다.


무선 환경에 영향을 주는 것들
WiFi 처럼 주파수 대역을 다른 통신 방식 (Bluetooth, …) 이나 전자렌지 같은 전자 제품과 공유하지 않는 경우에도, 무선 통신은 여러 가지 문제를 겪는다.

우선 무선 신호를 쏘면 이 신호는 감쇄 (attenuation 혹은 path-loss) 된다. 물리법칙에 의해 먼거리를 갈수록 신호 세기가 줄어든다. 그래서 스마트폰 게임을 할 때 기지국 (base station) 과의 거리가 멀면 통신 상태가 고르지 않은 경우가 있다.

또한 무선 신호는 중간의 장애물 등으로 인해 음영지역 (shadowing) 이 생길 수 있다. 특히 WiFi 나 3G, 혹은 LTE 에서 사용하는 주파수는 30 Mhz 보다 큰 상대적으로 고주파 대역이다.(수백에서 수 기가 Hz 정도의 영역) 이 경우 사실상 무선 신호는 직진하는 것에 가깝다. 그래서 장애물이 있다면 신호 전송이 쉽지 않다. 다만 상대적으로 큰 물체 — 예를 들어 큰 빌딩 — 에는 신호가 “반사” 해서 신호가 가기는 한다. 반사되면서 세기가 좀 줄어들기는 해도 말이다.

마지막으로, 직진해서 온 신호, (여러 경로로 )반사된 신호가 모두 스마트폰 등에 도착한다. 그러면 진행해 온 경로에 따라서 도착하는 시간에 미묘한 차이가 생기고, 이에따라 상쇄/보강 간섭도 일어난다. 그리고 좀 더 미세한 수준에서 보면, (시간 상으로) 이전에 보낸 신호가 늦게 도착해서, (시간 상으로) 현재에 해당하는 신호와 서로 간섭을 일으켜서 문제를 일으키기도 한다.

덤으로, 모바일 게임의 경우 한 자리에서만 플레이하는 것도 아니다. 걸어다니면서 (포켓몬 고?), 혹은 자동차나 지하철, 기차 등을 타고 이동하면서 플레이하는 것도 흔하다. 이 경우 기지국과의 이동 방향/속도에 따라서 도플러 효과가 발생하고, 인접한 주파수 대역을 쓰는 다른 통신, 혹은 자신의 통신의 다른 부분에 (악)영향을 준다.

유선 통신인 10G Ethernet 의 경우, 상대적으로 나중에 나온 표준이고 데이터센터 환경에 가까운 곳에서 쓰기 때문에 비트 오류율 (BER) 목표치가 대략 1/10^12 다. 즉, 1 Tbit 정도 보내면 오류가 하나 이하인 확률을 의미한다. 대략 이런 환경에서 하나의 일반 이더넷 (ethernet) 프레임 하나 (1500 bytes 정도)가 잘못 전송될 확률은 약 0.00000015 % 정도다. 거의 오류 날 확률이 없는 셈.

반대로 LTE 환경에서 최대 전송속도일 때 쓰는 64-QAM 의 경우 BER은 1/10^3 수준까지 올라갈 수도 있다. 아주 나이브하게 계산하면 이더넷 프레임 하나를 보냈을 때 오류 없이 전송할 확률이 22% 쯤 된다.


TCP 특성
TCP는 현재의 인터넷을 움직이는 가장 중요한 전송 프로토콜입니다. 아마 네트워크 간 연결 (즉 인터넷 그 자체) 을 담당하는 IP 만큼이나 중요한 프로토콜로 그 역사가 길기도 합니다. TCP 설계 철학과 구현에서 모바일에 영향을 받는 부분은 아래와 같다.

  • 종단간 원칙 (end-to-end principle): 통신하는 양쪽 끝의 주체 — 게임이라면 게임 서버와 클라이언트 — 에서 필요로하는 정보만 프로토콜에 담으며, 이를 이용해서 잘 할 수 있는 것만 처리. 예를 들어 TCP는 종단간 RTT 를 측정하고, 이를 이용해서 그 사이에 들어갈 수 있는 (전송 중인) 메시지 양을 추정하고, 이 값을 이용해서 혼잡 제어를 수행한다.
  • 약한 체크섬: 현대적인 관점에서 볼 때, 단순히 전체 메시지의 바이트 합으로만 이뤄진 16bit 체크섬은 오류를 복구할 수 없으며, 검출할 수 있는 오류 수에도 한계가 있습니다.
  • (상대적으로) 오류 없는 하위 계층에 대한 가정: TCP 메시지가 중간에 손실되거나 중복 전송되면 메시지가 없어진 이유가 적대적인 무선 환경 (혹은 데이터링크/물리 계층) 때문이 아니라, 메시지가 너무 많아서 생긴 혼잡 제어로 인해 없어진것이라고 가정하는 것.

 
■ 해결책
앞서 말한 내용만 놓고보면, 현대의 무선 통신은 오류도 엄청 날 것 같고, 그 오류 위에서 TCP를 쓰는건 말도 안되는 일 같다. 하지만 지금 모바일 게임을 플레이하면 전혀 그런 문제를 겪는 것 같지 않다. 왜 그런지 살펴봅시다.


채널 코딩
무선으로 신호를 보내는 (논리적이고도 물리적인) 주파수 대역을 “채널” 이라고 부릅니다. 이 채널에 신호를 보낼 때 0을 0, 1을 1로 보내는게 아니라,

  • 오류가 있다면 이걸 감지하고
  • 감지된 오류가 있다면 수정할 수 있는 여러 bit의 심볼로 변환하는

방식으로 바꿔서 보냅니다. 이런 방식을 오류를 인지하면 재전송하는 방식 (Backward Error Correction) 에 빗대어 FEC (Forward Error Correction) 이라고 부른다. 이런 변환은 “채널 코딩” 이라고 부릅니다. 가장 흔히 쓰이고, 다른 더 복잡한 채널 코딩 방식의 기반이 되는 컨볼루션 코드 (convolutional code) 는 다음과 같이 만든다.

2

  • 입력이 들어올 때마다 하나씩 오른쪽 레지스터로 시프트
  • 레지스터에 들어있는 값과 입력값이 각각 + 로 표시한 xor 게이트를 거쳐서 출력으로.
  • 입력에 대한 처리가 끝나면, 레지스터 값들이 0이 될 때까지 0을 추가로 넣는다. (그 동안 값도 출력으로 사용)

예제로 든 컨볼루션 코드는 1/3 rate 코드라고 부르는데, 입력 값 대비 출력 값이 세 배라서. 인코딩한 결과는 받는 쪽에서 SW를 사용하는 경우 Viterbi 알고리즘을 써서 다이너믹 프로그래밍으로 디코딩하거나, 이에 대응하는 Trellis diagram 을 하드웨어로 만든 구현을 써서 디코딩한다.

3

위 인코더에서 m_1 은 상태에 포함되지 않는 입력 값이라서, 상태 값은 2 bit으로 표현되고, 시작과 끝은 00 이고 이걸 이용해서 오류를 수정한다. 여기서 0이 들어왔을 때의 상태 전이를 실선, 1이 들어왔을 때의 상태 전이를 점선으로 표현하고, 한 bit 들어올 때마다 오른 쪽으로 한 칸씩 움직이는 걸 의미한다. 시작과 끝이 00 이고, 일부 bit이 오류일 수 있을 때, 이 중 가장 높은 확률인 경로를 찾는 다이너믹 프로그래밍 알고리즘이 Viterbi 알고리즘이다. 위 다이어그램에서 해당 알고리즘으로 붉은 선으로 표시된 것이 해당 경로다. (0, 1, 0, 1 이 전송된 것으로 판정)

추가로 이런 컨볼루션 코드 출력 결과를 양 끝단에서 서로 동의한 형태로 일부 bit을 제거해서 — puncturing 이라고 부른다 — 통신 환경이 양호할 때 오류율을 거의 증가시키지 않으면서 전송량을 늘릴 수도 있다.

터보 코딩과 LDPC
이 컨볼루션 코드는 802.11 WLAN — 흔히 말하는 WiFi — 나 GSM 을 사용하는 3G 통신 등에 광범위하게 사용한다. 이런 컨볼루션 코드를 기반으로 해서 더 좋은 성능 — 더 좋은 채널 코딩 후의 BER — 을 갖는 채널 코딩도 존재한다. 802.11ac 에서는 LDPC 를 써서 추가적인 성능을 끌어내고, LTE나 심우주 임무 (deep-space mission) 에서는 터보코드를 이용한다.

터보코드는 두 개의 컨볼루션 코드를 써서, 데이터, 데이터에 대한 패리티, 데이터의 순서를 (미리 정의한 방법을 써서) 섞은 것(인터리브)에 대한 패리티를 보낸다. (두 패리티를 각각 컨볼루션 코드 인코더를 이용해서 생성합니다) 디코딩하는 단계가 “터보”에 해당하는 단계입니다. 이 부분은,

  • 데이터에 대한 디코딩 — 단 0, 1을 고르는게 아니라 0, 1일 확률을 구하는 — 을 수행
  • 인터리브한 데이터에 대한 디코딩 (역시 확률을 구함)
  • 다시 이 데이터를 가지고 데이터 디코딩 (첫 단계의 반복)
  • 인터리브에 대한 디코딩을 수행

이렇게 데이터 디코딩을 반복해서 BER을 향상시키는 방식으로 동작한다. 그리고 반복마다 BER이 내려간다. (즉 더 잘 디코딩한다)

예를 들어 LTE 시스템에서 얘기하는 1/10^3 정도의 오류율을 갖는 채널이 있을 때, 이 위에 터보 코드를 끼얹으면 약 1/10^6 이하의 (유효한) BER로 감소한다. 즉, 이더넷 프레임을 하나 보낸다면 오류가 발생할 확률이 78% 에서 1% 이하수준으로 떨어진다. 또한 이 BER에서 전송이 실패했을 때는, ARQ가 자동으로 실패한 메시지를 재전송한다. (TCP와는 달리 MAC 수준에서는 수학적으로 훨씬 나은 CRC나 패리티를 이용하기 때문에, 에러가 감지되지 않고 TCP까지 올라갈 확률은 천문학적으로 낮다.)

TCP 강화
TCP는 그 긴 역사에 걸맞게 처음 프로토콜을 작성할 때완 다른 현재의 환경에 적합한 변경 사항들을 추가하고 있다. 앞에서 언급한 TCP의 문제는 다음과 같은 방책을 가지고 있다.

– 종단간 원칙 (end-to-end principle)
TCP 성능을 위해서는 종단간 왕복 시간 (RTT)에 대한 추정이 어느 정도 정확해야 한다. TCP 에 대한 RFC-7323 에선 TCP 헤더에 타임스탬프를 추가해서 RTT를 더 정확하게 측정할 방법을 제공한다. 이를 이용해서 네트워크 지연 시간의 변동으로 RTT를 제대로 측정하지 못해서 재전송이나 타임아웃이 일어나는 문제를 줄일 수 있다.

또한 대부분의 TCP 알고리즘 향상분은 OS 업데이트로 반영될 수 있어서 개발자가 크게 신경쓰지 않아도 된다. 예를 들어, TCP timestamp 가 추가된 linux kernel 버전으로 올리면 해당 효과를 바로 받을 수 있다. (현재 이미 광범위하게 사용되는 확장 기능) 비슷하게, Android 커널 버전이 올라가거나, iOS 버전업에도 비슷한 효과가 따라올 수 있다.

– 약한 체크섬
TCP 수준의 체크섬 오류가 일어나려면,

  • ECC 를 사용한 채널 코딩에서 에러 복구가 실패
  • 링크 계층의 체크섬 검사에서 확인 실패하고 통과 (CRC32)
  • IP 체크섬 검사 통과 (다만 IP의 체크섬은 TCP 수준으로 약함)

해야 가능하다. 그리고 처음 두 단계에서 대부분 걸러지기 때문에 실제로 문제를 일으킬 가능성은 매우 낮다.

– 오류 없는 하위 계층
WiFi 나 3G UMTS, 그 이후의 LTE 환경 등에서는 전송 오류 등이 발생하지 않도록 채널 코딩을 수행한다. 또한 전송 오류가 발생했을 때에도, 자동 재전송 메커니즘이 내장되어있기 때문에, 단순히 전송을 포기하는 것이 아니라 자동으로 해당 프레임을 재전송해서 TCP 계층에서 혼잡이 발생했다고 잘못판단할 가능성을 낮춘다.

TCP에서 재전송을 위한 타임아웃이 굉장히 긴데 (같은 ACK이 3번 온게 아닌 이상 2 RTT), 링크 계층의 재전송 시간은 LTE 의 경우 약 8ms 등으로 굉장히 짧아서 링크 수준의 전송 실패로 TCP 재전송이 일어날 가능성은 낮다.

■ 결론
모바일 / 무선 환경에서도 별 무리 없이 게임을 즐길 수 있는 것은 TCP 수준, 그리고 무선 통신 수준에서 광범위한 최적화가 이루어져서다. 무선 통신 수준에서는 물리적인 무선 통신 용량에 거의 근접한 채널 코딩 알고리즘이 적용되고 있으며, 새 무선 표준이 나올 때마다 — 그리고 해당 무선 표준이 통신사 망에 넓게 적용될 때 마다 — 더 나은 통신 방식으로 발전한다. 비슷하게 OS 수준의 TCP 기능 강화도 지속적으로 이뤄지고 있다. 앞으로도 이런 변화가 계속 될거라 기대하며 글을 마칩니다.

아이펀팩토리 김진욱 CTO

답글 남기기

댓글을 게시하려면 다음의 방법 중 하나를 사용하여 로그인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중