1.
미국에서 2005년을 넘어 2007년에 이르면 Latency가 밀리초를 기본으로 합니다.? 2009년에 이르면 마이크로초단위로 Latency를 측정합니다. 아마 2011년이후엔 나노초가 Latency를 계산하는 단위가 되지 않을까 합니다. 29West나 NYSE Technologies에서 Low Latency 메시징 미들웨어를 도입할 때 기준점은 100 마이크로초 였습니다. 반면 한국은 아직 밀리초를 벗어나지 못하고 있습니다. 이제 마이크로초단위로 접어드는 단계가 아닐까 합니다.
메시징을 담당하시는 파트너와 이런 저런 이야기를 하면서 잠시 의견을? 나눴던 부분이 “나노초단위로 측정할 있냐”는 이슈였습니다. 저는 외국 자료를 토대로 “가능하니까 자료에 넣지 않았겠냐!”는 입장을, 파트너는 “솔라리스등 OS에서 측정할 수 있는 한계가 있다”는 입장이었습니다.
예전에 적었던 것처럼 Latency는 End-To-End로 해야 합니다. 트레이딩의 경우 Market Data-To-Execution이라는 틀로 접근하여야 합니다. 시세를 멀티캐스팅하는 스위칭장비에서 시작하여 시세데이타를 받아서 주문을 생성하여 KRX로 주문메시지를 전송하는 순간까지를 측정하여야 합니다. 이상을 그림으로 표현하면 아래와 같습니다.
위의 그림은 미국의 사례지만 한국의 흐름과 꿰맞추어 보면 Tick Data Received By Data Vendor로 부터 시작해서 Order Sent To Execution Venue By Market Access Gateway까지입니다. 미국 Data Vendor에 의한 시세서비스를 사용하는 경우가 많기 때문에 Data Vendor가 들어갔습니다. 다만 Latency가 중요해지면서 거래소가 직접 데이타를 송신하는 경우가 많아지고 있습니다.
이상을 어플리케이션과 관련하여 Latency가 필요한 영역을 알아보도록 하겠습니다.
? 마켓데이타와 관련된 부분이 무척이나 복잡합니다. 거래소가 워낙 많고 RegNMS나 MiFiD에 의해 Best Execution의 의무가 있기때문에 시세데이타관리가 무척이나 중요합니다. Normalization이라는 부분은 거래소별로 포맷이 다르기때문에 내부시스템에서 단일한 API로 트레이딩을 하기 위한 형식변화를 위해 필요합니다.
2.
이제 어플리케이션에서 나노초단위로 어떻게 레이턴시(Latency) 측정을 하는지 알아보도록 하겠습니다.이하의 글은 개발자의 관점이 아닙니다. 혹 오류가 있으면 지적해주고 더 나은 방법이 있으면 알려주셨으면 합니다.
보통 Posix기반의 OS에서 보다 정밀한 시간 측정을 위한 함수로 gettimeofday ()를 제공하고 있습니다.
1 |
int gettimeofday (struct timeval *tp, void*); |
그렇지만 timeval structure (defined in time.h)를 보면 마이크로초까지 측정가능한 수준이라고 합니다.
1 2 3 4 |
struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }; |
그래서 timespec structure (also defined in time.h) 를 사용했다고 합니다.
1 2 3 4 |
struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; |
그렇지만 OS Patch가 이루어져 gettimeofday()에서 timespec 구조체를 사용할 수 있다고 합니다.아무튼 gettimeofday와 비슷한 기능을 하는 함수가 clock_gettime() 입니다.
1 2 |
#include <time.h> int clock_gettime(clockid_t clk_id, struct timespec *tp); |
매뉴얼을 보면 clockid_t clk_id에서 보통 두가지중 하나를 선택합니다.
* CLOCK_REALTIME (0) : 현재 시간을 기준으로 하여 시간을 계산. 시스템 시간 변경 시 영향을 받는다.
* CLOCK_MONOTONIC (1) : 커널이 동작한 시간을 기준으로 시간을 계산. 외부의 영향을 받지 않는다.
3.
이상과 같은 함수를 사용하여 어플리케이션에서 레이턴시(Latency)를 구하면 될텐데 그것이 그리 단순하지 않다고 합니다. 메시징제품으로 유명한 29West가 제기하는 문제를 살펴보도록 하겠습니다.
두 대의 서버를 놓고 레이턴시(Latency)를 측정하려면 시간을 동기화하여야 합니다. 보통 NTP(Network Time Protocol)서버를 사용하지만 측정단위가 나노초일 경우에 달라집니다. 오차범위가 어느정도냐에 따라 달라지지만 마이크로초수준이면 오차범위가 50%를 넘어설 수 있습니다. 따라서 서버A에서 서버B로 데이타를 보내고 측정하는 방법보다 Round-Trip을 추천합니다. 덧붙여 절대값이 상대값으로 측정하라고 권고합니다.
Another way to make precise latency measurements without synchronized clocks is to make round-trip measurements rather than one-way measurements. The local clock is read and inserted into the payload of a message. The message is sent to a receiver that echos it back. The time stamp from the echoed message is subtracted from the current clock reading to find the round trip time. Dividing this by two gives a very good approximation of the one-way latency if the two messages sent and received cover similar paths.
FAQ: Clock Synchronization for Latency Measurement중에서
이 때문에 gettimeofday() 보다 clock_gettime()을 사용하면 CLOCK_MONOTONIC값을 이용하라고 하는 사람도 있습니다.
gettimeofday() should never be used to measure time
반대로 29West는 NTP의 오류를 측정하여 gettimeofday()의 오차값을 확인하는 방법을 제시하고 있습니다. TSC(Time Stamp Counter)를 사용하는 것을 권고하기도 하고요.
Estimating Errors in Round-Trip Latency Measurements due to Clock Drift
문제는 이것만이 아닙니다. 컴퓨터의 시간이 하드웨어, 특히 CPU와 연관되고 CPU가 멀티코어기술을 도입하고 프로세서도 멀티쓰레드가 되면서 시간측정이 쉬운 일은 아닌 듯 합니다. NYSE가 이런 점을 토로하고 있습니다.
To track time on a nanosecond scale, NYSE will measure the elapsed time between a CPU’s clock ticks. A 3GHz processor, for instance, may have a clock tick every 3.5 nanoseconds, said Allen. The processes measured in nanoseconds are occurring on the same machine.
The interest in measuring in nanoseconds isn’t academic for the exchange’s clients, said Allen. There are hedge funds that want to know how far they are from the trading system’s matching engine because the longer the cable, the longer the delay. Every meter of cable length is about three nanoseconds — the speed of a signal through copper, he said.
But the value of measuring in nanoseconds may spur debate.Michael Salsburg, a distinguished engineer at Unisys Corp. who has been long involved with the Computer Measurement Group, said there are number of processes inside a CPU that could moot any nanosecond gains. For instance, where multiple core processors are sharing the same cache, “each one could be stealing cache from the other, which then causes more CPU cycles.” These CPU processes could easily drive times up to milliseconds, he said.
NYSE shrinks time measurement to nanoseconds중에서
3.
시간 측정을 하는 방법에 대해 여러가지로 읽어보니까 결국 OS커널과 하드웨어(CPU)를 이해하여야 가능하다는 생각을 했습니다. Timer라는 개념을 이해가 위해 커널, 하드웨어와 관련된 기능이 따라오기때문입니다.
커널연구회 리눅스 커널 들여다 보기
Timer In Linux
앞서 소개한 29West의 경우 TSC를 이용하는 방법이 어렵지만 좀더 정확한 방법이라고 합니다.
TSC is harder to use than software clocks like gettimeofday() because you can’t use it to measure time without first measuring the passage of time while the CPU runs to develop a conversion factor between CPU cycles run and time passed. This happens to be measuring the actual CPU clock frequency. You also have to watch out for processors that don’t sync TSC across cores and other gory details. It has the advantage of sub-microsecond resolution which becomes more important as we move to measuring latencies ever closer to 1 microsecond.
어려운 일입니다. 갑자기 몇 일전 소개하였던 글중 한 문장이 생각납니다.
Write efficient code for human reading and for CPU. It is never OK to write bad code.
빛의 속도가 3E8 m/s 이니깐, 1 n sec 동안 정보 전달의 최대 거리는 30cm 가 됩니다.
nano sec 라고 하면 보통 1~100 n sec를 얘기할테니, 정보 전달 거리가 0.3~30m 가 되겠죠.
따라서, n sec의 처리속도는 시세 데이터를 생성해서 전달하는 서버로부터의 거리가 대략 <100m
정도의 범위로 줄이는 노력이 있은 이후에나 유의미한 논쟁이 될 듯 싶네요.
(제가 트레이딩 시스템의 데이터 소스/전송등에 대해서는 잘 몰라서...)
반면 micro sec 라고 하면, 1~100 u sec일테고, 정보전달 거리는 300m ~30km가 되니,
서버와의 거리보다는 전산 처리 속도를 줄이는 것이 유의미하겠네요.
광케이블에서는 속도가 반으로 줄어든다고 하니까 1 나노초사이에 갈 수 있는 거리는 15cm이네요.(^^) 말씀하신 수치를 다 반으로 줄이면 될 듯. 그렇다고 글의 논지가 흐릿해지는 것은 아니라고 생각합니다.
증권사별 트레이딩센터를 어떻게 설계할지 몰라도 시세를 받는 곳으로부터 트레이딩서버를 지나 주문을 받은 서버에 이르는 거리의 편차가 10m이내가 아닐까 합니다. 말씀대로 수치화하면 70나노초정도의 차이. 그런데 현재 VIP시스템이나 DMA시스템에서 전산처리할 때 걸리는 시간은 1~10마이크로초.
역시나 같은 결론입니다.(^^)