2016-09-06 10 views
0

Windowsでrecvfrom関数に問題がありますが解決できません。
私が書いたコードの次の部分を参照してください。 LinuxとWindowsでこのコードを実行すると、udpのビットレート値が異なる結果になります。WindowsでCのrecvfrom関数がMinGWを使用しているときにUDPデータをスキップします

Cygwinを使ってWindowsでコンパイルすると、Ubuntuと同じ結果が得られます。大丈夫です。私はこれを参考ツールと比較した。

MinGWを使用してWindowsでコンパイルすると、1秒間のwhileループの反復回数(カウンタ変数)が小さくなり、関連するものが少なくなるため、より小さなupdビットレート値が得られます。 1秒(data_in_1_sec変数)。 MinGWを使用してWindowsでrecvfrom funtionが遅く、udpデータをスキップしているようです。
ビットレートが約0.200Mbpsの場合、両方のOSでMinGWを使用した場合の結果は同じです。 UDPビットレート約20 Mbpsのデータで問題が確認できます。

残念ながら、このコードが静的ライブラリとしてPythonコードにロードされているため、MinGWを使用する必要があります。 CygWinのDLLを使用して、Pythonでこの関数を実行しているときにアクセス違反が発生します。

これに対処するには?このコードの

while (1) { 
    #ifdef _WIN32 
     // start timer 
     QueryPerformanceCounter(&t1);   
    #elif __linux 
     clock_gettime(CLOCK_MONOTONIC, &start); 
    #endif 

    udp_packet_len = recvfrom(sock, udp_packet, buff_len, 0, (struct sockaddr *) &addr, &addrlen); 
    #if DEBUG == 1 
     counter++; 
    #endif 

    #ifdef _WIN32 
     // stop timer 
     QueryPerformanceCounter(&t2);   
    #elif __linux 
     clock_gettime(CLOCK_MONOTONIC, &finish); 
    #endif 

    data_in_1_sec += (double)udp_packet_len; 

    #ifdef _WIN32 
     temp = (t2.QuadPart - t1.QuadPart); 
     temp *= 1000000000.0;  
     temp /= frequency.QuadPart; 
     temp /= 1000000000.0; 
     second += temp; 
    #elif __linux 
     temp = (finish.tv_sec - start.tv_sec); 
     temp += (finish.tv_nsec - start.tv_nsec)/1000000000.0; 
     second += temp; 
    #endif 

    if(second >=1.0) { 
     processing.udp_bitrate = (((data_in_1_sec) * 8.0) /second); 

     #if DEBUG == 1 
      fprintf(stderr,"\nudp_bitrate: %f\n",processing.udp_bitrate); 
      fprintf(stderr,"data_in_1_sec: %f\n",data_in_1_sec); 
      fprintf(stderr,"second: %f\n",second); 
      fprintf(stderr,"counters: %d\n",counter); 
      counter = 0; 
     #endif 

     data_in_1_sec = 0; 
     second = 0.0; 
    } 

結果、Windows用
:同じデータのためのUbuntu用

udp_bitrate: 19799823.828382 
data_in_1_sec: 2505664.000000 
second: 1.
counters: 1904 

udp_bitrate: 19389475.566430 
data_in_1_sec: 2451708.000000 
second: 1.011562 
counters: 1863 

udp_bitrate: 18693904.033320 
data_in_1_sec: 2367484.000000 
second: 1.013158 
counters: 1799 

udp_bitrate: 18963187.258098 
data_in_1_sec: 2399068.000000 
second: 1.012095 
counters: 1823 

udp_bitrate: 19452989.621014 
data_in_1_sec: 2459604.000000 
second: 1.011507 
counters: 1869 

udp_bitrate: 19795284.196391 
data_in_1_sec: 2509612.000000 
second: 1.014226 
counters: 1907 

出力

は、私が使用しているWindows 7 Professionalの64

コードを使用します

udp_bitrate: 22016976.870087 
data_in_1_sec: 2788604.000000 
second: 1.013256 
counters: 2119 

udp_bitrate: 22022223.539749 
data_in_1_sec: 2787288.000000 
second: 1.012536 
counters: 2118 

udp_bitrate: 22003055.797884 
data_in_1_sec: 2785972.000000 
second: 1.012940 
counters: 2117 

udp_bitrate: 22041580.024322 
data_in_1_sec: 2788604.000000 
second: 1.012125 
counters: 2119 

udp_bitrate: 22025510.655441 
data_in_1_sec: 2782024.000000 
second: 1.010473 
counters: 2114 

udp_bitrate: 22412560.109513 
data_in_1_sec: 2801764.000000 
second: 1.000069 
counters: 2129 

答えて

0

UDPは信頼性の低いトランスポートです。パケットの廃棄は許可された動作であり、データ送信レートが受信者によってデータが処理されるレートを上回るところで予想される。

CygwinとMinGWは別々のプロジェクトです。彼らはそれぞれ独自のrecvfrom()ラッパーをWindowsカーネルとAPIの上に構築して提供しています。 Cygwinの実装は、あなたのテストの条件の下でMinGWより10%大きな帯域幅を提供する、より効率的であると考えられます。

測定が測定に干渉している可能性もあります。 Cygwinの少なくともいくつかのバージョンでは、デフォルトでプリプロセッサによって_WIN32が定義されているのに対し、MinGWはそうでないため、Cygwinでclock_gettime()、MinGWでWindowsパフォーマンスカウンタを使用している可能性があります。このような違いが無視できる程度にWindowsパフォーマンスカウンターのオーバーヘッドは十分に低いと思われますが、多くの呼び出しを行います。 固定数の固定数のテストを実行し、すべての反復の合計のタイミングだけを計時することで、両方のソースからのオーバーヘッドを最小限に抑えることを検討する必要があります(レート計測ごとに1つのタイマ開始/停止)。

ボトムライン:テスト方法を改善することができますが、結果がテスト中のさまざまな実装の動作をよく反映していても、根本的に間違っていることは明らかになりません。

関連する問題