0

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

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

MinGW を使用して Windows でコンパイルすると、更新ビットレート値が小さくなります。これは、1 秒間の while(1) ループの反復回数が少ない (カウンター変数) ことと、関連するもの - 1 秒間にキャプチャされるデータの量が少ない (data_in_1_sec) ことが原因です。変数)。MinGW を使用した Windows での recvfrom 関数は、最も遅く、udp データをスキップするようです。
ビットレートが約 0.200 Mbps の場合、MinGW を使用した場合、両方の OS で同じ結果になることに注意してください。問題は、UDP ビットレートが約 20 Mbps のデータで見られます。

残念ながら、このコードはスタティック ライブラリとして Python コードに読み込まれるため、MinGW を使用する必要があります。CygWin dll を使用すると、Python でこの関数を実行しているときにアクセス違反が発生します。

これに対処する方法は?

Windows 7 Professional 64 を使用しています。

私が使用するコード:

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の場合、このコードの結果:

udp_bitrate: 19799823.828382
data_in_1_sec: 2505664.000000
second: 1.012399
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

同じデータのUbuntuの出力

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
4

1 に答える 1

0

UDP は信頼性の低いトランスポートです。パケットのドロップは許可された動作であり、データ送信レートが受信機によって処理されるデータのレートを超えていることが予想されます。

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

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

結論: テスト方法論は改善される可能性がありますが、結果がテスト対象のさまざまな実装の動作を適切に反映している場合でも、根本的な問題は明らかになりません。

于 2016-09-06T15:03:48.487 に答える