テキストの処理や描画を行う GDI32.dll の関数を複数の CPU 上で並行して実行すると時間がかかる

Windows XP のサポートは終了しました

マイクロソフトでは、2014 年 4 月 8 日に Windows XP のサポートを終了しました。この変更は、ソフトウェアの更新プログラムおよびセキュリティ オプションに影響しています。 この変更の意味および保護された状態を維持する方法について説明します。

Windows Server 2003 のサポートは 2015 年 7 月 14 日で終了しています

Windows Server 2003 のサポートは 2015 年 7 月 14 日で終了しています。この変更は、ソフトウェアの更新プログラムおよびセキュリティ オプションに影響します。 この変更の意味および保護された状態を維持する方法について説明します。

現象
テキストの処理や描画を行う GDI32.dll の関数を、繰り返し大量に実行するスレッドを用意します。
1 回の関数呼び出しにかかった時間を以下の 2 つのケースで計測すると、ケース 2 よりもケース 1 の方が、1 回の関数呼び出しに時間がかかります。
  1. CPU が複数搭載されているコンピューターにおいて、それぞれ別の CPU 上でこのスレッドを 4 つ開始します。
  2. CPU が複数搭載されているコンピューターにおいて、1 つの CPU 上で 4 つすべてのスレッドを開始します。

原因
GDI32.dll は、テキストの処理や描画を行う以下のような関数を提供しています。

  • ExtTextOut 関数
  • GetCharWidth32 関数
  • PlayEnhMetaFile 関数

これらの関数内部では、テキストの処理や描画に必要な情報を得るために、Win32 の GDI が管理している非公開のグローバル データに対してアクセスを行うことがあります。
そして Win32 の GDI 内部では、複数のスレッドから同時にアクセスされることがないように、このグローバル データを排他制御しています。

ところが、複数の CPU 上でこれらの関数が並行して大量に実行されると、排他制御されているグローバル データへのアクセス待ちが大量に発生するため、それぞれの関数呼び出しに時間がかかることがあります。

また、前述した 3 つの関数だけでなく、Win32 の GDI が管理しているグローバル データに対してアクセスを行う GDI32.dll の関数すべてで、同じ理由により時間がかかることがあります。

なお、マルチスレッドを利用して PlayEnhMetaFile 関数などメタファイルを扱う API を実行した場合、正しく印刷できない場合や例外が発生する可能性があります。こちらは、GDI32.dll において メタファイルを扱う API がスレッドセーフでないために発生します。 
回避策
以下のいずれかの方法でこの問題を回避することが可能です。
  • 複数の CPU 上でそれぞれの関数が並行して大量に実行されることがないように、各スレッドまたはプロセスを実装してください。
  • それぞれの関数を呼び出すスレッドまたはプロセスができるだけ同じ CPU 上で実行されるように、各スレッドまたはプロセスに CPU アフィニティ マスクを設定して実行してください。

状況
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。
注意 : これは、マイクロソフトのサポート組織内で直接作成された "緊急公開" の資料です。 この資料には、確認中の問題に関する現状ベースの情報が記載されています。 情報提供のスピードを優先するため、資料には誤植が含まれる可能性があり、予告なしに随時改定される場合があります。 その他の考慮事項については、使用条件を参照してください。
プロパティ

文書番号:2864443 - 最終更新日: 09/29/2016 15:03:00 - リビジョン: 4.0

Microsoft Windows XP Home Edition, Microsoft Windows XP Professional, Microsoft Windows Server 2003, Standard Edition (32-bit x86), Microsoft Windows Server 2003, Standard x64 Edition, Microsoft Windows Server 2003, Enterprise Edition (32-bit x86), Microsoft Windows Server 2003, Enterprise x64 Edition, Microsoft Windows Server 2003 R2 Standard Edition (32-bit x86), Microsoft Windows Server 2003 R2 Standard x64 Edition, Microsoft Windows Server 2003 R2 Enterprise x64 Edition, Windows Vista Home Basic, Windows Vista Home Basic 64-bit edition, Windows Vista Home Premium, Windows Vista Home Premium 64-bit edition, Windows Vista Business, Windows Vista Business 64-bit edition, Windows Vista Ultimate, Windows Vista Ultimate 64-bit edition, Windows Vista Enterprise, Windows Vista Enterprise 64-bit edition, Windows Server 2008 Datacenter, Windows Server 2008 Standard, Windows Server 2008 Enterprise, Windows 7 Home Basic, Windows 7 Home Premium, Windows 7 Professional, Windows 7 Ultimate, Windows 7 Enterprise, Windows Server 2008 R2 Datacenter, Windows Server 2008 R2 Standard, Windows Server 2008 R2 Enterprise, Windows 8, Windows Server 2012 Datacenter, Windows Server 2012 Standard, Windows Server 2012 Essentials, Windows Server 2012 Foundation

  • kbbug kbnofix kbexpertiseinter kbexpertiseadvanced KB2864443
フィードバック