流程
- 將test.cu代碼進行分離,利用cudafe.exe 去分離CPU代碼和GPU代碼,我們可以在生成的中間檔案可以看到test.cudafe1.cpp和test.cudafe1.gpu
- cicc.exe 將根據編譯選項-arch=compute_xx將GPU代碼編譯成對應架構的test.ptx檔案
- ptxas.exe 編譯 test.ptx 到test.cubin,這個是根據編譯選項-code=sm_xx定義的,比如test.sm_30.cubin.(這一步叫做PTX離線編譯,主要的目的是為了將代碼編譯成一個確定的計算能力和SM版本,對應的版本資訊保存在cubin中)
- fatbin.exe 編譯test .cubin 和test. ptx到 text.fatbin.c , (這一步叫PTX在線編譯,是將cubin和ptx中的版本資訊保存在fatbin中)
- 呼叫系統的gcc/g++將host代碼(test.cudafe1.cpp)和fatbin(text.fatbin.c)編譯成對應的目標檔案test.o 和test._dlink.o,
- 用c++編譯器將目標檔案鏈接起來生成可執行檔案,
實驗
nvcc --cuda test.cu --keep --dryrun
細節
- -arch=compute_XX, -code=sm_XX, 如果寫兩個的話必須這樣來寫,也就說compute_必須對應的是arch, code必須對應的是sm_,arch代表的是目標機器(vitural),而code代表的是真實機器(real),下面是具體的例子:
nvcc -o test test.cu -arch=compute_35 -code=sm_70 --keep --verbose
具體小步驟
- cicc *** -arch compute_35 -o test.ptx// 可以看出ptx是根據arch來設定的
- ptxas -arch=sm_70 -m64 “test.ptx” -o “test.cubin”//本地二進制檔案是根據sm_70來設定,至于為用的是arch,這就是nvcc瞎寫
- fatbinary --create=“test.fatbin” -64 “–image=profile=sm_70,file=test.cubin” --embedded-fatbin=“test.fatbin.c” --cuda(這里面沒有將ptx放進去不知道什么情況,當只有arch一個引數的時候ptx和cubin都會放入fatbin.c里面)
使用
一般都是只使用一個-arch, 這樣默認你的arch和code是同一個架構算力,比如-arch=sm_70,感覺英偉達這搞得一點也不規范,都出亂編,也沒個統一的標準,
思考
- 經常可以看到說cuda的即時編譯,可是我是沒見到運行的時候出現編譯程序,難道是我使用姿勢不對?
fatbinary機制,exe二進制檔案中會包含一個或多個體系結構的二進制代碼以及PTX代碼來完全避免JIT成本,CUDA運行時會在二進制檔案中查找當前GPU架構的代碼,并在找到時運行它,如果找不到二進制代碼,但PTX可用,則驅動程式將編譯PTX代碼,這樣,部署的CUDA應用程式可以在新GPU出現時支持它們,nvcc x.cu -arch=compute_10 -code=compute_10,sm_10,sm_13,比如這一段程式,編譯出來的代碼就會有10,13兩個二進制,實際遇到了這類GPU就直接使用,否則就把compute_10.ptx運行時編譯一波,
- 難道我一份exe每次在新機器A上重復使用時每次都要即時編譯嗎?這也太蠢了吧
快取機制, 如果在code中沒有指示出來實際運行的GPU, 理論來說你在A這個GPU上運行的時候,每次都要JIT,為此cuda做了一個優化,就是將它第一次接觸過得GPU卡即時編譯后快取一起,也就是說第一次在A卡編譯后,下次再運行就直接可以呼叫快取里面的二進制了,理論上來說就是放在-code=sm_10, A,sm_20,不過A是在遇到A之后才編譯的
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/237221.html
標籤:其他
上一篇:車輛網專案架構設計
下一篇:部署主從資料庫
