2
void* worker(void*)
{
    int clk = clock();
    float val = 0;
    for(int i = 0; i != 100000000; ++i)
    {
        val += sin(i);
    }
    printf("val: %f\n", val);
    printf("worker: %d ms\n", clock() - clk);
    return 0;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, worker, NULL);
    int clk = clock();
    float val = 0;
    for(int i = 0; i != 100000000; ++i)
    {
        val += sin(i);
    }
    printf("val: %f\n", val);
    printf("main: %d ms\n", clock() - clk);
    pthread_join(tid, 0);
    return 0;
}

メイン スレッドとワーカー スレッドは同じ速度で実行されるはずですが、結果は次のようになります。

   val: 0.782206
   worker: 5017 ms
   val: 0.782206
   main: 8252 ms

メインスレッドがずっと遅いです。理由はわかりません....


問題が解決しました。これはコンパイラの問題で、Windows で GCC(MinGW) の動作がおかしいのです。Visual Studio 2012 でコードをコンパイルしましたが、速度に違いはありません。

4

2 に答える 2

1
 Main thread and the worker thread are supposed to run equally fast, but the result is:

このような保証を提供するリアルタイム OS 以外のスレッド システムは見たことがありません。Windowsスレッドと他のすべてのスレッドシステム(私はposixスレッドも使用しており、MacOS Xの軽量スレッドとC#スレッドのスレッド)をデスクトップシステムで使用すると、パフォーマンスの保証がないことを理解しています。 1 つのスレッドが別のスレッドと関連します。

考えられる説明 (推測) としては、最新のクアッドコアを使用しているため、メイン コアのクロック レートが上がっている可能性があります。ほとんどがシングル スレッドのワークロードである場合、最新の i5/i7/AMD-FX システムは、1 つのコアのクロック レートを、ストック冷却で熱を放散できる定格レベルまで上げます。より多くの並列ワークロードでは、すべてのコアのクロック速度の上昇が小さくなり、熱放散に基づいて事前に評価され、アイドル状態のときにすべてのコアが抑制されて、電力使用量が最小限に抑えられます。バックグラウンド作業のほとんどが 1 つのコアで実行され、2 番目のスレッドが 2 番目のコアで費やす時間が、すべてのコアの速度を上げるモードへの切り替えを正当化するのに十分でない可能性があります。

4 つのスレッドと 10 倍のワークロードで再試行します。CPU 負荷とクロック速度を監視するツールがある場合は、それを確認します。その情報を使用して、私が正しいか間違っているかを推測できます。

別のオプションとして、プロファイリングを行い、作業のどの部分に時間がかかっているかを確認することもできます。OS の呼び出しにワークロードよりも多くの時間がかかっている可能性があります。

また、安定したクロック速度やシングル コアなど、さまざまなパフォーマンス特性を持つ別のマシンでソフトウェアをテストすることもできます。これにより、より多くの情報が得られます。

于 2013-06-11T15:42:07.703 に答える