2012-12-05 46 views
4

我編寫了一個包含多個子例程的CUDA程序。當我禁用子例程A時,運行時改進了數量a。當我禁用子程序B時,運行時間改進量b。當我禁用子程序A和B時,運行時間改善量爲c> a + b。兩個子程序都是完全獨立的。二進制代碼長度對CUDA程序性能的影響

這接下來的部分可能是分析這是一個幼稚的做法,但這裏是我做過什麼:我編譯的代碼的每個版本和跑了每個二進制cuobjdump自卸薩斯。對於完整的二進制文件,結果輸出約爲1350行,對於每個二進制文件,其中一個子程序被禁用約1100行。如果我禁用了這兩個子程序,我得到了850行。看起來,我需要3.1美元每行的前三個和2.4美國的兩個子程序被禁用。

由於A和B不包含任何複雜的內容或比其他代碼更加深入地使用內存,我不認爲這是由於註釋掉所有的時間密集型操作而導致簡單的活動而引起的。我的猜測是禁用A和B的程序代碼仍然適合流式多處理器的指令緩存,而其他版本的指令緩存太大。這可能會導致全局內存訪問,以便可以加載更多程序代碼,並且延遲會導致此差異。不幸的是我找不到指令緩存大小的任何信息。

任何人都可以幫我解釋這些結果嗎?

+3

進行此類分析時,您需要非常小心。 GPU編譯器和彙編器具有非常積極的「死代碼刪除」優化。如果編譯器可以確定代碼段不會影響寫入全局內存的結果,那麼它只會從內核中刪除整段代碼。 – talonmies

+0

是的,但是當我運行cuobjdump --dump-sass?我想知道運行時間的下降,以及這可能與二進制代碼的長度有關。 – volker

+1

當前版本的CUDA分析器不顯示指令高速緩存統計信息。 Nsight Visual Studio版CUDA Profiler確實顯示停滯原因。如果主要的失速原因是Fetch,那麼內核可能會破壞icache,或者你有很多跳轉。進一步的解釋將需要分析報告和審查代碼。 –

回答

0

可能有幾件事情導致你的結果。有些人可能會包括:

  • 一個& B的缺乏導致剩餘碼的一些額外的優化。生成的代碼可能不是更短,但仍可能執行得更快。

  • 優化器發現A中的某些代碼也存在於B中(A和B可能仍然是獨立的)。因此,兩個A & B的運行速度比使用單獨的A和單獨的B要慢。

  • 只有A或B(或兩者都不)會導致更好的內存訪問模式或更多的高速緩存命中剩餘代碼。 (我正在談論數據,而不是程序代碼)

  • 缺少A和B可能會導致更好的佔用率,允許更多的線程同時運行。

我非常懷疑指令緩存可能是問題。即使全局內存讀取是必要的,但它永遠不會「錯位」,因爲變形總是隻需要一條指令。我的猜測是,他們使用一些專用的硬件進行說明。

+0

我想所有這些都是可能的。我認爲第一個案例適合我的計劃。我做了一個循環的實驗,這個循環在一個版本中展開,而不是在另一個版本中展開。由此產生的更大的二進制代碼不會在運行時造成顯着差異,增加重複次數只會增加運行時線性,如預期的那樣。儘管_cuobjdump --dump-sass_的輸出大小有時會很奇怪,但這似乎並不影響運行時,這讓我想知道「死」的代碼是否有時會存在於優化器中。 – volker