6

時々、この単純なプログラムを実行すると

#include <Windows.h>

DWORD WINAPI ThreadStart(LPVOID)
{
    for (;;) { }
    return 0;
}

int _tmain()
{
    SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);

    SYSTEM_INFO si;
    GetSystemInfo(&si);
    for (DWORD i = si.dwNumberOfProcessors * 2; i > 0; i--)
    { CloseHandle(CreateThread(NULL, 0, &ThreadStart, NULL, 0, NULL)); }

    Sleep(INFINITE);
}

次のような不公平なスレッド スケジューリングが常に見られます。

スクリーンショット

すべての実行で不公平ではありませんが、そうである場合、アプリケーションの存続期間を通じて不公平なままです。

なぜこれが起こるのですか?それを回避する適切な方法は何ですか?

4

4 に答える 4

1

プログラムの一部ではないスレッドが実行されるたびに、マルチプロセッサ システムでこれが表示されます。起動して数秒間実行するシステム タスクがあり、.NET アセンブリなどをスキャンしているとします。他のコアのスレッドが実行を続けている間、スレッドの 1 つが多数のタイム スライスのスケジューリングから除外されます。ノックアウトされたスレッドは、他のスレッドに追いつくことはありません。

于 2013-05-09T08:55:59.967 に答える
1

いくつかのオプション:


Windows 7/8 64 ビット (32 ビットではない)、または Windows Server 2008 R2 以降を実行している場合 (およびその場合のみ) 、システム スケジューラを完全にバイパスして、自分でこれを処理できます。ささいな仕事!

MSDN here で説明されており、 User-Mode Scheduling (UMS)と呼ばれています。

以下の MSDN のスクリーンショットの一部 - これは役に立ちますか?

ここに画像の説明を入力

さらに、Windows が論理コアと物理コアをどのように区別するかについては議論があるため、(適切な場合) BIOS でハイパースレッディングを無効にすることをお勧めします。ディスカッションについては、こちらを参照してください

SetThreadAffinityMask()MSDN here)のような利用可能な機能もいくつかありSetThreadIdealProcessor()、個人的にはこれが少し行き当たりばったりであることがわかりましたが、役立つかもしれません。全体的なスループットを向上させるよりも、むしろ損なうことがよくあります。

于 2013-05-09T06:18:18.643 に答える
0

これは暗い推測のショットです。

ただし、ハイパースレッディングが結果を少し歪めている可能性があることをお勧めします。

一部のコンピューターのように、ラップトップの bios/cmos でハイパースレッディングを無効にできる場合は、コードが実際のコアでのみ実行されている数値を確認すると興味深いでしょう。

そして、HTがスレッドに偏る理由であるとしても、なぜそうするのかはまだわかりません。

于 2013-05-09T07:05:33.553 に答える