U E D R S I H C RSS
ID
Password
Join
우리가 아무 것도 세상에 가지고 온 것이 없음에 또 한 아무 것도 가지고 가지 못하리니 우리가 먹을 것과 입을 것이 있은 즉, 족한 줄로 알 것이다. - 성서


네트워크 시뮬레이션을 실행하는데 있어서 기본적인 문제점 한가지는 지속적이고, 밀리초단위의 정확한 시각을 세션상의 모든 호스트들에 걸쳐서 일정하게 유지해야한다는 점입니다. 이러한 시간동기화는 호스트와 당사자사이의 충돌체크, 이벤트 스케줄링, 경로 예측을 가능하게 만들어줍니다.

초보적인 해결책은 상대편 호스트에 핑정보를 받아 지연시간을 추정하는 방식으로 처음 시작때 한번 시간을 맞추는 것입니다. 불행하게도 이것은 잘 동작하는 방법이 아닙니다. (This doesn't work well, unfortunately, because even hardware timers can drift over time -- cheap clock crystals, time registers on overclocked CPUs, or just inconsistent results from different hardware on the same machine.)

다행스럽게도, 이 분야에는 많은 실용적인 연구가 있어왔습니다. 네트워크 시간동기화 프로토콜(NTP : Network Time Protocol)은 표준 단위 시간으로 인터넷 호스트들을 동기화시켜줍니다. 만약 여러분이 정밀도에 대하여 매우 심각하게 생각하고 있다면, 여러분만의 연구를 시작해야만 할 겁니다. 하지만 게임 디자이너로서 저는 이러한 복잡함 모두를 원하지 않은 까닭에, 몇가지 기술을 수용하고 더 간단한 알고리즘을 구현해 보았습니다.
  1. 우선 호스트는 자신의 클럭으로부터 초기 타임기록을 unsigned 32비트 정수형으로 기록해둡니다. 모든 다른 클라이언트들은 세션에 의존한 시간(이것은 자신의 하드웨어와 네트워크가 허락하는 정도만큼만 정확한 시간을 말합니다)동안 자신의 인증을 지연시킵니다.
  2. 다른 호스트들은 주기적으로 (말하자면 대략적으로 매 3 또는 5초마다) 자신들의 시간을 받아두고, 서버로 "핑 패킷"안에 이 값을 넣어 보냅니다. 이 핑 수치는 일반적인 데이타 패킷에 붙여보낼 수도 있을겁니다.
  3. 서버도 자신의 시간값을 얻어낸다음, 결과를 추가한다음 "퐁 패킷"에 담아 전송함으로서 가능한한 빨리 응답합니다. 전송이 포기되거나 극도로 느리게 전송된 패킷은 부정확한데다 쓸모없으므로 재전송하지 않습니다.
  4. 메세지가 도착하면, 클라이언트는 한번더 응답시간을 기록합니다. 이제 클라이언트는 3개의 값을 가지게 되었습니다: 이전의 시간기록, 서버의 시간기록, 최종응답 시간기록. 다시한번, 매우 느린 응답(10초이상)일경우 즉시 그 패킷은 버립니다.
  5. 이들 값을 통하여, 왕복 시간과 평균 지연시간을 계산하는건 쉽게 할 수 있습니다. 서버의 시간기록에 평균 지연시간을 더함으로서, 클라이언트는 실제 자신의 시간을 파악할 수 있습니다.
  6. 가장 최근 32 또는 64 핑 정보를 담을 수 있는 배열안에 왕복시간을 기록합니다.
  7. 임시 배열을 생성하고 그 안을 증가된 순서대로 시간값을 채웁니다.
  8. 20%, 50%, 80%위치에 해당하는 값을 추출하거나 또는 비슷한 통계 연산을 실행합니다. (예 : 표준편차)
  9. 만약 가장최근 핑 패킷에 대한 왕복시간이 20% 위치안에 존재하고, 클럭이 3밀리초이후에 등장했다면 클라이언트는 자신의 클럭이 "정확한"시간으로 간주합니다.

위에 언급한 퍼센트비율값은 약간 임의로 정한 것이지만, 몇몇 방법에서는 네트워크 성능의 좋은 기준이 될 수 있습니다.
  • 20% 지점: 현재 연결된 부분에서 최상의 핑 절대시간값이므로, 어플리케이션은 더 나아질 것이라고 기대하지 않습니다. 시간동기화에 있어서 가장 정확한 핑 패킷을 선택하기위해 이 값을 사용합니다.
  • 50% 지점: 중간치는 실제로 핑 지연시간의 절반을 의미합니다. 이 값(또는 실제 평균값)을 지정한 패킷이 회선을 거쳐오는데 얼마나 걸렸는지 예상하기위해 사용하시기 바랍니다.
  • 80% 지점: 대부분의 패킷들은 이 시간내에 도착하므로, 이것은 메세지가 "늦게" 도착했을때를 진단하는데 사용합니다. A reliable packet that hasn't been acknowledged by twice this value (round trip time) should be considered lost or late -- and resent.

다음 그림은 정렬한다음 퍼센트 비율에 따라 나누어 놓은, 현재 시간기록들의 배열을 나타낸 것입니다. 80% 지점이후의 패킷시간이 빠르게 그리고 불규칙하게 증가하는 경향이 있다는 점에 주목하시기 바랍니다. 이것은 전형적으로 백본망 트래픽 또는 라우터 과부하와 같은 네트워크 상태 변화에 따른 것입니다.

howto1table.gif

여러분은 32비트 시간기록정보를 전송하는 것은 대역폭의 낭비라고 생각할수도 있습니다 - 이것은 여러분의 생각이 맞습니다. 32비트 밀리초 타이머는 대략 50일정도의 시간범위를 표현할 수 있지만, 단지 16비트 타이머값을 전송하는 것은 +/- 32초정도의 시간범위를 가지게 됩니다. This means that you can reduce your packet size by stripping off the most signficant bits of the timestamp, and then extrapolating them on the remote side. This must be done immediately, though, because a slow packet may actually spend 30 seconds on the wire or in a queue waiting for acknowledgement.

한번 매 시스템마다의 시간이 서로서로 대략 6 밀리초이내로 정확하게 맞춰진다면, 시간기록을 비교하고 실시간에서 진단 또는 예측을 실행하기 쉬워집니다. 두 이벤트 A와 B사이의 경과시간을 측정하려면, 단지 시간기록을 빼고 ( A-B ) 결과치가 "양수인지 음수인지" 여부를 보면 됩니다.

  • 양수: 이벤트 A는 이벤트 B보다 ( A-B ) 밀리초만큼 이후에 발생했습니다.
  • 음수: 이벤트 A는 이벤트 B보다 ( A-B ) 밀리초만큼 이전에 발생했습니다.
  • 0: 이벤트 A는 이벤트 B와 동시에 발생했습니다.

물론 문제가 아직 남아있습니다. 네트워크 지연시간으로 인해 정확성이 제한될 수 밖에 없으며, 주기적인 오류는 클럭값을 "불안하게" 만들수 있습니다. 한가지 방법은 매 시간마다 3에서 7밀리초만큼 허용치를 넓혀주는 것인데, 이렇게 하면 처음 시작때는 잘 동기화 되며 차후 심하게 시간이 밀릴경우에만 처리하게 됩니다.

비대칭 링크인 경우에는 전혀 다른 문제인 경우입니다. 호스트 X에서 호스트 Y로의 지연시간이 Y에서 X로의 지연시간보다 두드러지게 큰 경우(예를 들면, 몇몇 케이블 모뎀은 다운로드시에는 이더넷을 사용하지만, 업로드에는 아날로그 모뎀을 사용합니다), 실제로 핑 페킷의 왕복시간을 사용하여 측정하는 것은 불가능합니다. 이런 경우와 다른 네트워크 시간측정 문제는 활발히 연구중에 있습니다.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-10-28 12:42:52
Processing time 0.3297 sec