e7UDP/IPを使ったFPGA-PC間の通信レイテンシをはかってみた

技術紹介

GbE版のe7UDP/IPを使ってPCからFPGAにパケットを送って返ってくるまでのレイテンシをはかってみました.

注: あくまで,この数字は今回はかってみたという範囲での測定結果です.測定結果は十分に検証されてものではありませんので,ご容赦ください.

測定(1)

測定環境

測定環境として用意したのはこんな感じの構成

e7udpip_measure_test

Linuxが走っているホストPCから,FPGAにUDPパケットを投げて返ってくるまでの時間を測定します.パケットは,FPGA内部でプロトコル処理をされた後で,折り返されていることに注意してください.実験に使ったPCのスペックは次の通り.

CPU Core i7-3770K 3.50GHz
メモリ 32GB
OS CentOS 6.6 (Linux kernel 2.6.32)
ネットワークI/F Intel 82572EI GbE
コンパイラ gcc 4.4.7 

測定に使ったプログラム

単純にUDPパケットを作って投げて受信するというのを繰り返すだけのプログラムです.ただし,(1)ソケットのオープン/クローズを含む場合(SOCK_ONETIMEを定義しない場合),と,(2)ソケートのオープン/クローズは含まない場合(SOCK_ONETIMEを定義する場合),で測定してみます.

測定結果は,それぞれ100,000回の送受信を繰り返すのにかかった時間を測定し,その時間を100,000で割った値を1回の送受信にかかるレイテンシとみなしています.

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>

double get_time(){
  struct timeval t;
  double usec;
  
  gettimeofday( &t, NULL );
  
  usec = t.tv_sec + t.tv_usec / 1000000.0;
  return usec;
}

int main(int argc, char** argv){
  int sock, i;
  struct sockaddr_in addr;

  char b0[1024];
  char b1[1024];
  double t0, t1;

  addr.sin_family = AF_INET;
  addr.sin_port = htons(16385);
  addr.sin_addr.s_addr = inet_addr("10.0.0.1");

#ifdef SOCK_ONETIME
  sock = socket(AF_INET, SOCK_DGRAM, 0);
  bind(sock, (struct sockaddr *)&addr, sizeof(addr));
#endif

  t0 = get_time();

#ifndef TIMES
#define TIMES (100000)
#endif
 
  for(i = 0; i < TIMES; i++){

#ifndef SOCK_ONETIME
  sock = socket(AF_INET, SOCK_DGRAM, 0);
  bind(sock, (struct sockaddr *)&addr, sizeof(addr));
#endif

    sendto(sock, (void*)b0, sizeof(b0), 0, (struct sockaddr *)&addr, sizeof(addr));
    recv(sock, (void*)b1, sizeof(b1), 0);
    
#ifndef SOCK_ONETIME
  close(sock);
#endif

  }

  t1 = get_time();
  printf("elapsed time (for %d times)= %lf sec.\n", TIMES, (t1-t0));
  printf("elapsed time (for a time)= %lf sec.\n", (t1-t0)/TIMES);

#ifdef SOCK_ONETIME
  close(sock);
#endif

  return 0;
}

結果

結果は次の通り.まあ,こんなもの,なのでしょうか…

ソケットのオープン/クローズを含む場合 145μ秒
ソケットのオープン/クローズを含まない場合 101μ秒

測定(2)

環境

今度は,間にスイッチを挟んでみる事にします.

e7udpip_measure_test2

使用したスイッチは,PLANEXのFXG-16IRMです.

結果

結果は次の通り.スイッチを挟んだ場合と比べてレイテンシは長くなりました.ところで,ソケットのオープン/クローズを含む場合と含まない場合での差が小さくなったのがちょっと不思議.システムコール呼び出しの間隔が変わったから,とか?もう少し調査が必要です.

ソケットのオープン/クローズを含む場合 159μ秒
ソケットのオープン/クローズを含まない場合 150μ秒

測定(3)

環境

さらにスイッチを多段にしてはかってみます.たとえば,2段スイッチをはさむと次のようになります.

e7udpip_measure_test3

結果: スイッチを2段挟んだ場合

PC <-> FXG16IRM<->GS108(NETGEAR)<->FPGAという構成です.同じスイッチが用意できなかったのはご愛嬌ということで…

ソケットのオープン/クローズを含む場合 203μ秒
ソケットのオープン/クローズを含まない場合 154μ秒

 

結果: スイッチを3段挟んだ場合

PC <-> FXG16IRM<->GS108(NETGEAR)<->DGS-3420-28TC(D-Link)<->FPGAという構成です.DGS-3420-28TCはGbEと10GbEのスイッチですが,GbEのポートだけを使います.

ソケットのオープン/クローズを含む場合 214μ秒
ソケットのオープン/クローズを含まない場合 200μ秒 

結果: スイッチを4段挟んだ場合

さらにもう一段挟んでみます.

PC <-> FXG16IRM<->GS108(NETGEAR)<->DGS-3420-28TC(D-Link)<->LSW-GT-4W(BUFFARO)<->FPGAという構成です.

ソケットのオープン/クローズを含む場合 217μ秒
ソケットのオープン/クローズを含まない場合 201μ秒

結論?

なかなかリニアに増えるものではなく,どこでどう時間を消費しているのかよみとるのが難しいですね…といわけで,結論というほどのものは言えないですが,今回の計測につかった1024のパケットではれば,約8μ秒がパケットバッファを一段とおるのに必要な時間です.FPGA同士を対向させた場合の測定結果がe7udpipのレイテンシを測定してみただったのですが,今回計測した限りでは,ソフトウェアではFPGAに比べて+50μ秒程度のオーバヘッドがかかる,とは言えそうです.

コメント

タイトルとURLをコピーしました