[英]OpenCL: Distinguishing computation failure from TDR interrupt
當使用還運行主顯示屏的GPU在Windows上運行長時間的OpenCL計算時,操作系統可能會通過“ 超時檢測和恢復”來中斷計算。
以我的經驗(Java,通過NativeLibs4Java使用JavaCL和NVidia GPU進行使用),這在繞開clEnqueueReadBuffer時表現為“資源不足”(cl_out_of_resources)錯誤。
問題是,由於其他原因(例如,由於訪問無效的內存),我在使用OpenCL程序時會得到完全相同的消息。
是否存在(半)可靠的方法來區分由TDR引起的“資源不足”和由其他問題引起的“資源不足”?
或者,我是否至少可以可靠地(在Java中/通過OpenCL API)確定用於計算的GPU也正在運行顯示器?
我知道這個問題,但是答案與clFinish不返回的情況有關,這對我來說不是問題(到目前為止,我的代碼從未在OpenCL API中凍結)。
是否存在(半)可靠的方法來區分由TDR引起的“資源不足”和由其他問題引起的“資源不足”?
1)
如果可以訪問
KeyPath : HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\GraphicsDrivers KeyValue : TdrDelay ValueType : REG_DWORD ValueData : Number of seconds to delay. 2 seconds is the default value.
從WMI乘以
KeyPath : HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\GraphicsDrivers KeyValue : TdrLimitCount ValueType : REG_DWORD ValueData : Number of TDRs before crashing. The default value is 5.
再次與WMI。 將這些乘以10秒。 而且,你應該得到
KeyPath : HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\GraphicsDrivers KeyValue : TdrLimitTime ValueType : REG_DWORD ValueData : Number of seconds before crashing. 60 seconds is the default value.
應該從WMI讀取60秒。
對於此示例計算機,在達到崩潰限制的最后60秒之前需要5 x 2秒+1的額外延遲。 然后,您可以從應用程序中檢查最后一個秒表計數器是否超過了這些限制。 如果是,則可能是TDR。 除此以外,還有從驅動程序退出線程的時間限制,
KeyPath : HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\GraphicsDrivers KeyValue : TdrDdiDelay ValueType : REG_DWORD ValueData : Number of seconds to leave the driver. 5 seconds is the default value.
默認為5秒。 訪問無效的內存段應更快退出。 也許您可以將這些TDR時間限制從WMI延長到幾分鍾,以便它可以使程序進行計算而不會因搶占性飢餓而崩潰。 但是更改注冊表可能很危險,例如,將TDR時間限制設置為1秒或其中的一部分,那么Windows可能永遠不會在沒有持續TDR崩潰的情況下啟動,因此讀取這些變量必須更加安全。
2)
您可以將全部工作分成更小的部分。 如果數據不可分離,請復制一次,然后將長時間運行的內核作為非常短距離的內核入隊n次,並且在任意兩次之間等待一些時間。
然后,您必須確保刪除了TDR。 如果運行此版本但長時間運行的內核未運行,則表示TDR錯誤;相反,則是內存崩潰。 看起來像這樣:
short running x 1024 times
long running
long running <---- fail? TDR! because memory would crash short ver. too!
long running
另一種嘗試:
short running x 1024 times <---- fail? memory! because only 1ms per kernel
long running
long running
long running
或者,我是否至少可以可靠地(在Java中/通過OpenCL API)確定用於計算的GPU也正在運行顯示器?
1)
使用兩個設備的互操作性屬性:
// taken from Intel's site:
std::vector<cl_device_id> devs (devNum);
//reading the info
clGetGLContextInfoKHR(props, CL_DEVICES_FOR_GL_CONTEXT_KHR, bytes, devs, NULL))
這給出了可互操作的設備列表。 如果您不想使用它,則應獲取它的ID以將其排除。
2)
讓另一個線程運行一些opengl或DirectX靜態對象繪制代碼,以使其中一個GPU保持繁忙。 然后使用另一個線程對一些通用的opencl內核代碼同時測試所有GPU。 測試:
執行此操作時,請勿在設備之間復制任何數據,以免CPU / RAM成為瓶頸。
3)
如果數據是可分離的,則可以使用分而治之的算法,使任何GPU僅在可用時才發揮作用,並讓顯示部件具有更大的靈活性(因為這是性能感知型解決方案,可能類似於short-運行版本,但計划在多個GPU上完成)
4)
我沒有檢查,因為我賣出了第二代GPU,但是,您應該嘗試
CL_DEVICE_TYPE_DEFAULT
在您的多GPU系統中測試它是否獲得顯示GPU。 關閉計算機,將監視器電纜插入其他卡,然后重試。 關閉,更改卡座,然后重試。 關閉,取出其中一張卡,這樣僅剩1 gpu和1 cpu,請重試。 如果所有這些都只顯示display gpu,則應將display gpu標記為默認值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.