メモ
OpenCL1.1 泥沼メモ 【解決編】
OpenCL や CUDA は、GPUを汎用並列計算用の資源として使うためのフレームワークです。
計算中は当然、本来 GPU が担うはずの画像出力のための演算をおざなりになります。
GPUを用いた並列計算のためのシステムとして、計算用のGPUを用意している場合は問題ありませんが、
GPU一つの常用PC でGPU並列計算を行った場合には「2秒ルール」が適用されて、
「ディスプレイ ドライバー NVIDIA Windows Kernel Mode Driver,Version xxx.xx が応答を停止しましたが、正常に回復しました」と、せっかくの計算を強制的に止められてしまいます。
これは、画面描画のためのGPUドライバの応答が無くなったとOSが判断した際に、 GPUドライバを強制的に再起動するために起こります。
たとえ処理自体にエラーがなくても単に「2秒」経過すると引き起こされるため、このままでは科学系の重い計算をさせることができません。
このGPUドライバの再起動は、OSの再起動を伴わずに問題を解消するために Windows に組み込まれた Windows Display Driver Model (ウィンドウズ・ディスプレイ・ドライバ・モデル、WDDM) と呼ばれる Visuta 以降で導入されたビデオドライバ用の枠組みで実行されます。つまり、レジストリの変更でタイムアウトの時間(既定2秒)を任意の時間に変更することができるということです。
レジストリでタイムアウトの時間を設定する
「regedit.exe」を起動し、以下の2つのディレクトリで新規に「DWORD値」の項目を追加します。
1:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/GraphicsDrivers
2:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/GraphicsDrivers/DCI
追加する項目
TdrLevel: REG_DWORD
「0」:検出無効・・・タイムアウトしない
「1」:回復なしでバグチェック
「2」:VGA への回復(?)
「3」:タイムアウト時に回復する(既定)
TdrDdiDelay: REG_DWORD
ドライバ停止後にドライバを回復させるまでの時間(既定5秒)
回復するまでバクチェックを行う。
TdrDelay: REG_DWORD
タイムアウトまでの時間(既定2秒)
これをいじることで、ドライバの再起動の時間を任意に設定することができる。
自分は「TdrLevel」を「0」にしました。
簡単な巨大配列演算を OpenCL で実行した結果、CPU単一スレッドと比較して100倍の速度が得られました。
これは単純に、これまでスレッド10個で1週間必要だった計算が約1日弱で計算できることになります。
【動作環境】
OS: Windows 7 64bit
CPU: Intel corei7 3930K (6コア12スレッド)
GPU: NVIDIA Geforce GTX680 (2GB)
ちなみに、NVIDIA Geforce GTX680 は CUDAコアが 1536(これが同時並列計算可能数)、最大スレッド数(最大ワークアイテムの数)が 1024×1024×64 です。
参考
■ WDDM によるタイムアウトの検出と GPU の回復
■ Video drivers constantly crashing in VMware