2

スレッドがスリープ状態のスレッドをウェイクアップするために呼び出したときのレイテンシーを測定しようとしていました。多くの同期プリミティブが futex の上に開発されていると言われているので、futex は常に高速であると期待しています。しかし、私のテストでは反対の結果が得られました。何か悪いことをしたのだろうか、それとも事実なのだろうか。

私のテストの詳細は次のとおりです。

  • プロセスは特定のコアにアフィニティを設定されています
  • 時間は RDTSC() 命令から返された数によって比較されます
  • 2 つのスレッドが作成され、ウェイク中のスレッド 2 の FIFO 優先度が高くなります。

Thread1 はミューテックスのロックを解除してシグナルを送信しているため、Thread2 は次のスケジュールでウェイクアップすることになっています。thread1 の sleep(1) は、mutex_unlock が呼び出されたときに、thread2 がミューテックスを待機してスリープ状態になるようにするためのものです。

void *Thread1(void *dummy)
{
    while(1)
    {
        pthread_mutex_lock( &mutx );
        sleep(1);
        t1 = rdtsc();
        pthread_mutex_unlock( &mutx );
        pthread_yield();
    }
    return NULL;
}

void *Thread2(void *dummy)
{
    while(1)
    {
        pthread_mutex_lock( &mutx );
        t2 = rdtsc();
        if(t1>0)
        {
                    // print out the result
            cout << t2-t1 << endl;
            t1 = 0;
        }
        pthread_mutex_unlock( &mutx );
        pthread_yield();
    }
    return NULL;
}

同様のテストは、mutex を futex システム コールに置き換えることによって行われます。

void *Thread1(void *dummy)
{
    while(1)
    {
        sleep(1);
        t1 = rdtsc();
    syscall(SYS_futex, &futx, FUTEX_WAKE, 1);
        pthread_yield();
    }
    return NULL;
}

void *Thread2(void *dummy)
{
    while(1)
    {
        syscall(SYS_futex, &futx, FUTEX_WAIT, 0);
        t2 = rdtsc();
        if(t1>0)
        {
            cout << t2-t1 << endl;
            t1 = 0;
        }
        pthread_yield();
    }
    return NULL;
}

mutx と futx の両方がグローバルに宣言されています。私の Core i7 930 マシンで、fedora17 を使用すると、mutex は一貫して futex よりも 5 ~ 10% 速くウェイクアップします。テスト アプリケーションは、デフォルト設定で gcc 4.7 によってコンパイルされました。なにか提案を?前もって感謝します。

4

1 に答える 1

1

ミューテックスの Futex ベースの実装は、ロック/ロック解除操作に対して syscall を実行しませんが、必要な場合にのみ実行します。

ミューテックスのロック/ロック解除を無条件の futex システムコールに置き換えると、遅くなる必要があります。

于 2013-01-16T18:50:59.507 に答える