2012-12-03 81 views
2

我得到一個CUDA_EXCEPTION_5,傳出超範圍地址錯誤,我試圖找出可能導致這種情況的各種情況。寄存器溢出是否可能導致CUDA_EXCEPTION_5,超出範圍地址錯誤?

我正在將C項目(由其他人編寫)移植到CUDA。 C代碼的寄存器非常重,實例化堆棧中的許多數組。我假設寄存器溢出很可能會發生,並且可能會引發錯誤超出範圍的錯誤。

請注意,我想先讓它工作,然後我將開始優化代碼。

我使用Compute Capable 3.0硬件,根據維基百科有512KB「每個線程的本地內存」。我在其他地方看過它每個SM有512KB的寄存器空間。每個正在運行的線程可能有512KB的寄存器空間嗎?

我正在執行我的內核如下(是的,我知道這是超慢):

dim3 grid(28800,1); 
cuPlotLRMap<<<grid,1>>>(...) 

一些細節(我不知道如何有幫助這將是):

我硬件有7個SM。有112個運行模塊,這是否意味着每個模塊獲得512k的寄存器空間的1/16?

我也明白,如果一個線程超過了它可以溢出到全局內存的寄存器空間。發生這種情況時,併發線程是否有可能溢出到同一個全局內存空間中?

+0

在CUDA中沒有「註冊溢出」這樣的事情。 GPU使用靜態編譯時間分配寄存器分配。永遠不會有「溢出」或越界寄存器訪問。 – talonmies

+0

@talonmies ok,因此在內核中聲明一個巨大的數組(即:int = 44800; float * s = new float [n];')可能超慢,但不應該是上述內核異常的原因?堆棧是無限的?我在追一隻紅鯡魚嗎?使用new關鍵字創建變量是否將變量放在全局內存中,還是保留在本地內存中? – Sean

+0

@talonmies我將退後一步,在另一個線程中詢問關於調試器的問題。我可能會誤解我必須尋找的東西。 – Sean

回答

2

512KB「每個線程的本地存儲器」。我在其他地方看過,每個SM有512KB的 寄存器空間。每個運行線程是否可以有512KB的寄存器空間 ?

請參閱CUDA C編程指南中的Compute Capabilities表。計算能力2.x及以上版本的設備最多支持每個線程512KB的本地內存。可以使用函數cudaDeviceSetLimit(cudaLimitStackSize,bytesPerThread)來設置該值。我相信每個線程的默認值是2 KB。

我的硬件有7個SM。有112個運行模塊,這是否意味着每個模塊獲得512k的寄存器空間的1/16?

計算能力3.x設備每個多處理器最多可以有16個塊。這假設您的寄存器/線程,線程/塊或共享內存/塊不會將內核限制爲小於設備最大值。 Visual Profiler和Nsight VSE CUDA Profiler內核使用的配置。

目前,您只能啓動1個線程/塊。您應該啓動每個塊的多個WARP_SIZE(32)。

我也明白,如果一個線程超過了它可以溢出到全局內存的寄存器空間。發生這種情況時,併發線程是否有可能溢出到同一個全局內存空間中?

在編譯或JIT時間,編譯器將執行寄存器分配。如果每個線程沒有足夠的寄存器,那麼編譯器會溢出到本地內存。該操作是確定性的,並且在運行時不確定。

計算能力3.0設備限於63個寄存器/線程。計算能力3.5設備限制爲每個線程255個寄存器。

+0

感謝您的解釋。如果編譯器決定將數組存儲在本地內存中,那麼數組中的每個元素佔用一個寄存器還是整個​​數組佔用一個63的寄存器? – Sean

+0

@Sean:本地內存不駐留在寄存器文件中。它存儲在受保護的全局內存的每個線程分配中。 – talonmies