2012-03-04 5 views
0

네트워킹 프로젝트의 일부로 네트워크 프로그램을 작성했습니다. 프로그램은 패킷 묶음 (berkely socket API를 사용하는 통신에 사용되는 TCP)을 생성하고 특정 포트로 보내고 응답을 가져옵니다. 이 프로그램은 완벽하게 작동하지만, 프로그램에서 실제로 생성되는 데이터 속도와 같은 백 엔드 계산을하고 싶었습니다. 내가 시도한 것은 패킷을 내보내고 그 시간까지 전체 데이터를 나눈 코드의 루틴 전후의 시간을 측정했다는 것입니다 : 총 799 개의 패킷이 루틴에서 한 번에 전송됩니다. 각 패킷은 82 바이트이므로Linux에서의 C에서의 패킷 생성 속도 측정

799x82x8 = 524144 비트. 측정 된 시간이었다 = 0.0001s 데이터 속도, 524,144/0.0001 = 여기에 5.24 Gbps의

내가 노력 코드의 조각이다 그래서 :

struct timeval start,end; 

double diffTime (struct timeval* start, struct timeval* end) 
{ 
    double start_sec = ((double) start->tv_sec) + (double) start->tv_usec/1000000.00; 
    double end_sec = ((double) end->tv_sec) + (double) end->tv_usec/1000000.00; 
    return (end_sec - start_sec); 
} 
while(1){ 
gettimeofday(&start, NULL); // getting start time 

*/ Call packet sending routine */ 

gettimeofday(&end, NULL); 

printf("Time taken for sending out a batch is %f secs\n", diffTime(&start,&end)); 
} 

내가 문제를 접근하고 있는지 확인하고 싶었다는 바르게 또는 아닙니다. 또한 이것이 올바른 방법이라면 이더넷 인터페이스에서 패킷의 실제 물리적 속도 인 i-e에서 패킷이 어느 속도로 빠져 나가고 있는지 실제로 알 수있는 방법이 있습니까? 프로그램에서 계산 한 패킷 속도 (사용자 모드에 있으며 사용자/커널 장벽이 시스템 호출에서 지나치게 많을수록 속도가 느릴 것으로 예상 함)와 실제 패킷 속도의 차이점을 추정 할 수 있습니까? 모든 도움을 많이 주셨습니다.

감사합니다.

+1

65K 패킷 크기로 인해 얻게되는 타이밍에 대한 결론을 이끌어 낼 수 있는지 여부는 확실하지 않습니다. 데이터 양은 매우 작으므로 기본적으로 대역폭보다는 연결 대기 시간 만 측정합니다. –

+0

그건 의미가 있습니다. 더 현실적인 결과를 얻기 위해 시도 할 수있는 다른 것이 있습니까? – Abdullah

+0

예, 더 많은 데이터가 포함 된 더 많은 패킷을 보내십시오. 또한 처음부터 패킷을 생성하는 데 필요한 실제 시간을 측정하려고 시도하면 재미있을 수도 있습니다. –

답변

1

나는 그것이 당신이 원하는 것이 아닌 것으로 의심합니다. 당신이 가지고있는 것은 당신에게 정보를 줄 것이지만 그것을 향상시키는 방법에 관한 지표가 아닐 것입니다.

일반적으로 걱정되는 것은 소켓 send/recv 관계에서 걸리는 시간을 측정하는 것입니다. 이것은 일반적으로 sends() 또는 recv()의 어떤 형태로 기다리는 시간을 측정하는 데 걸리는 시간을 측정하는 것과 관련이 있습니다.

일반적으로 볼 수있는 몇 가지 사항이 있습니다. 전송 계층을 수집하고 버퍼링하기 위해 네트워크 계층에 의존하고 있습니까? 아니면 버퍼링을하고 데이터를 전송하려는 경우에만 전송을 수행합니까? 만약 후자가 보통 nagle 버퍼링을 끄고 싶다면 (setsockopt과 TCP_NODELAY를 보라), 코드가 회귀하지 않도록 조심한다.

다음은 버퍼링입니다. 아마도 데이터가 소켓 버퍼링에 걸리는 시간을 측정하고있을 것인데, 이는 거의 순간적 일 것입니다. 응답 패킷의 확인/조정을 통해 스트리밍하는 경우 오랜 기간 동안 정상적으로 평균화됩니다. setsockopt() 및 SO_RCVBUF/SO_SNDBUF를 사용하여 버퍼링을 처리 할 수 ​​있습니다.

조금 더 자세히 설명 할 예정입니다. perf에 대한 물리적 네트워크가 아닌 코드를 측정하고 가능한 가장 큰 블록에서 패킷을 보내고받는 경우 일반적으로 확인해야 할 두 가지가 더 있습니다.

  1. ACK 유형 프로토콜이 있습니까? 코드는 기본적으로/recv를 패턴으로 보냅니다. 그렇다면 대기 시간이 가장 큰 문제 일 수 있습니다. 독립적으로 스트리밍되는 여러 개의 보류중인 요청을 허용하는 것에서 sliding windows을 구현하는 방법에 이르기까지 여러 가지 방법으로 해결할 수 있습니다. 주요 아이디어는 단지 데이터의 흐름을 방해하지 않는 것입니다.

  2. 마지막으로 recv()를 다루는 경우 일반적으로 스레드/프로세스 당 하나의 소켓 관계 만 처리하려는 경우가 아니라면 recv에서 차단하지 않는 것이 좋습니다. 오래된 학교 솔루션은 select()였으며 합리적인 확장 성을 위해 여전히 실행 가능합니다.대규모 솔루션의 경우 epoll (linux), kevents (osx) 또는 IOCP (windows)를 찾습니다. 이것들은 당신이 계좌 관리와 (때로는) 쓰레드 풀링을 OS로 되돌려 줄 수있게합니다. 문제는 실제로이 NIC을 펌프 아웃 할 수있는 데이터의 양에 관한 것입니다. 여러 연결을 처리하지 않는 한 거의 필요하지 않습니다.

내가 정말로 묻는 것을 놓친 경우 미안하지만 일반적인 문제를 다루려고했습니다.

+0

이런 것들을 지적 해 준 조에게 감사드립니다. 나는 이들 중 일부를 돌 보았다. 비동기 I/O 멀티플렉싱을 수행하는 프로그램에서 여러 클라이언트를 에뮬레이션 할 때 poll()을 사용합니다. 모든 통화가 차단되지 않습니다. 나는 데이터 속도 부분을 측정하는 것에 매달려 있었고, 그것에 관해 어떤 경험이 없었기 때문에 이것을 시도했다. 장기간에 걸쳐 평균을 구하는 것은 패킷을 대량으로 보내고 평균 시간을 계산해야한다는 것을 의미합니까? – Abdullah

+0

나는 '안정된 상태'를 유지 한 후에 시간이 지남에 따라 성능을 확실히 볼 것입니다. 최소한 가장 느린 속도, 가장 빠른 속도, 그래 ... 아마도 표준 편차까지 추적하여 네트워크의 예측 가능성을 알고 싶을 수도 있습니다. (http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance) – Joe