カーネルオブジェクトを使用して異なるCPUで実行されているスレッドを同期する場合、他のOSと比較してWindows Server 2008 R2を使用すると、実行時のコストが増える可能性がありますか?
編集:そして、回答からわかるように、質問には「より低いCPU使用率レベルで実行している場合」というフレーズも含める必要があります。私はこの質問に対する私自身の答えにもっと多くの情報を含めました。
バックグラウンド
プロセス間の通信に共有メモリとセマフォを使用する製品に取り組んでいます(2つのプロセスが同じマシンで実行されている場合)。Windows Server 2008 R2(この後Win2008R2に短縮)のパフォーマンスの問題の報告により、Win2008R2の2つのスレッド間でセマフォを共有するのが他のOSに比べて比較的遅いことがわかりました。
それを再現する
次のコードを2つのスレッドで同時に実行することで、それを再現することができました。
for ( i = 0; i < N; i++ )
{
WaitForSingleObject( globalSem, INFINITE );
ReleaseSemaphore( globalSem, 1, NULL );
}
Windows Server 2003R2SP2とWindowsServer2008 R2をデュアルブートするマシンでテストすると、上記のスニペットはWin2003R2マシンでWin2008R2と比較して約7倍高速に実行されます(Win2003R2では3秒、Win2008R2では21秒)。
テストの簡単なバージョン
以下は、前述のテストの完全版です。
#include <windows.h>
#include <stdio.h>
#include <time.h>
HANDLE gSema4;
int gIterations = 1000000;
DWORD WINAPI testthread( LPVOID tn )
{
int count = gIterations;
while ( count-- )
{
WaitForSingleObject( gSema4, INFINITE );
ReleaseSemaphore( gSema4, 1, NULL );
}
return 0;
}
int main( int argc, char* argv[] )
{
DWORD threadId;
clock_t ct;
HANDLE threads[2];
gSema4 = CreateSemaphore( NULL, 1, 1, NULL );
ct = clock();
threads[0] = CreateThread( NULL, 0, testthread, NULL, 0, &threadId );
threads[1] = CreateThread( NULL, 0, testthread, NULL, 0, &threadId );
WaitForMultipleObjects( 2, threads, TRUE, INFINITE );
printf( "Total time = %d\n", clock() - ct );
CloseHandle( gSema4 );
return 0;
}
詳細
テストを更新して、スレッドが1回の反復を実行し、各ループで次のスレッドに強制的に切り替えるようにしました。各スレッドは、各ループの最後で実行するように次のスレッドに信号を送ります(ラウンドロビンスタイル)。また、セマフォ(カーネルオブジェクト)の代わりにスピンロックを使用するように更新しました。
私がテストしたすべてのマシンは64ビットマシンでした。テストは主に32ビットとしてコンパイルしました。64ビットとして構築された場合、全体的に少し速く実行され、比率がいくらか変更されましたが、最終的な結果は同じでした。Win2008R2に加えて、Windows 7 Enterprise SP 1、Windows Server 2003 R2 Standard SP 2、Windows Server 2008(R2ではない)、およびWindows Server2012Standardに対しても実行しました。
- 単一のCPUでのテストの実行は、大幅に高速化されました(SetThreadAffinityMaskでスレッドアフィニティを設定し、 GetCurrentProcessorNumberでチェックすることで「強制」されました)。当然のことながら、単一のCPUを使用すると、すべてのOSで高速になりましたが、カーネルオブジェクトの同期を使用したマルチCPUとシングルCPUの比率は、Win2008R2の方がはるかに高かった。Win2008R2を除くすべてのマシンの一般的な比率は2倍から4倍でした(複数のCPUでの実行には2倍から4倍の時間がかかりました)。しかし、Win2008R2では、比率は9倍でした。
- ただし...すべてのWin2008R2マシンで速度低下を再現することはできませんでした。私は4でテストしました、そしてそれはそれらのうちの3つで現れました。ですから、これに影響を与える可能性のある何らかの構成設定やパフォーマンス調整オプションがあるのではないかと思わずにはいられません。パフォーマンスチューニングガイドを読み、さまざまな設定を確認し、さまざまな設定(バックグラウンドサービスとフォアグラウンドアプリなど)を変更しましたが、動作に違いはありません。
- 必ずしも物理コア間の切り替えに関係しているとは限りません。私は当初、異なるコア上のグローバルデータに繰り返しアクセスするコストに何らかの形で関係しているのではないかと思っていました。ただし、同期に単純なスピンロック(カーネルオブジェクトではない)を使用するバージョンのテストを実行する場合、さまざまなCPUで個々のスレッドを実行すると、すべてのOSタイプでかなり高速になりました。マルチCPUセマフォ同期テストとマルチCPUスピンロックテストの比率は、通常10倍から15倍でした。しかし、Win2008R2 Standard Editionマシンの場合、比率は30倍でした。
更新されたテストの実際の数値は次のとおりです(時間はミリ秒単位です)。
+----------------+-----------+---------------+----------------+
| OS | 2 cpu sem | 1 cpu sem | 2 cpu spinlock |
+----------------+-----------+---------------+----------------+
| Windows 7 | 7115 ms | 1960 ms (3.6) | 504 ms (14.1) |
| Server 2008 R2 | 20640 ms | 2263 ms (9.1) | 866 ms (23.8) |
| Server 2003 | 3570 ms | 1766 ms (2.0) | 452 ms (7.9) |
+----------------+-----------+---------------+----------------+
テストの2つのスレッドは、それぞれ100万回の反復を実行しました。これらの精巣はすべて同一のマシンで実行されました。Win Server2008およびServer2003の番号は、デュアルブートマシンからのものです。Win 7マシンの仕様はまったく同じですが、物理マシンは異なります。この場合のマシンは、Corei5-2520M2.5GHzを搭載したLenovoT420ラップトップです。明らかにサーバークラスのマシンではありませんが、実際のサーバークラスのハードウェアでも同様の結果が得られます。括弧内の数字は、指定された列に対する最初の列の比率です。
この1つのOSがCPU間のカーネルレベルの同期に余分な費用を導入するように見える理由について何か説明はありますか?または、これに影響を与える可能性のある構成/調整パラメーターを知っていますか?
これは非常に冗長で長い投稿になりますが、必要に応じて、上記の番号から取得したテストコードの拡張バージョンを投稿することもできます。これは、ラウンドロビンロジックとスピンロックバージョンのテストの実施を示しています。
拡張された背景
なぜこのように行われるのかについての避けられない質問のいくつかに答えようとすること。そして、私は同じです...私が投稿を読んだとき、私はしばしば私がなぜ尋ねているのか疑問に思います。だからここにいくつかの試みが明確になります:
- アプリケーションは何ですか?データベースサーバーです。状況によっては、顧客はサーバーと同じマシンでクライアントアプリケーションを実行します。その場合、(ソケットよりも)通信に共有メモリを使用する方が高速です。この質問は、共有メモリ通信に関連しています。
- ワークロードは本当にイベントに依存していますか?ええと...共有メモリ通信は名前付きセマフォを使用して実装されています。クライアントはセマフォに信号を送り、サーバーはデータを読み取り、応答の準備ができたらサーバーはクライアントにセマフォに信号を送ります。他のプラットフォームでは、目がくらむほど速くなります。Win2008R2では、そうではありません。また、お客様のアプリケーションにも大きく依存します。彼らがサーバーへの小さなリクエストをたくさん使ってそれを書いた場合、2つのプロセスの間にはたくさんのコミュニケーションがあります。
- 軽量ロックは使用できますか?おそらく。私はすでにそれを見ています。しかし、それは元の質問とは無関係です。