這是今天在羣裏有人問了這麼一個問題
cudaMemcpyToSymbol
可以將數據從host拷貝到global,cudaMemcpy
也是從host到>global,這種情況下二個函數有什麼區別嗎?
和各位大佬討論一下後,和大家分享一下~
首先,學到了cudaMemcpyToSymbol
竟然還有將數據從host拷貝到global的功能,以前只用過這個函數拷貝constant memory。拷貝方式的不同是由目的內存申請的方式決定的。申請的是device內存,cudaMemcpyToSymbol
拷貝就是從host拷貝到global。申請的是constant內存,cudaMemcpyToSymbol
拷貝就是從host拷貝到constant memory。
__device__ float g_damp_x[MAX_DIM];
__constant__ float c_damp_y[MAX_DIM];
然後大家開始各種猜測,性能方面的問題、設計方面的問題以及兼容性方面問題等等。下面是我的一些見解,很榮幸得到了各位大佬的贊同,跟大家分享一下。
我是從GPU性能仿真器GPGPU-Sim(http://www.gpgpu-sim.org)入手的,通過看Sim中這個兩個函數部分的代碼,可以看到這個兩個函數的執行過程。
cudaMemcpy
函數的過程比較簡單,只是做了一些安全判斷後就像模擬global內存中根據“地址”將數據寫到global內存中(GPGPU-Sim是通過物理內存來模擬GPU內的各種內存)。
而cudaMemcpyToSymbol
函數的過程實現的比較複雜,具體在cuda-sim/cuda-sim.cc
文件的1554行的gpgpu_ptx_sim_memcpy_symbol
函數中,在這個函數中,在根據目標地址在global memory和constant memory中進行搜索。代碼如下:
if( g_globals.find(hostVar) != g_globals.end() ) {
found_sym = true;
sym_name = hostVar;
mem_region = global_space;
}
if( g_constants.find(hostVar) != g_constants.end() ) {
found_sym = true;
sym_name = hostVar;
mem_region = const_space;
}
然後再根據搜索結果將數據寫到不同的內存中,所以根據以上觀察的結果,cudaMemcpy在性能會更好一些。
PS:今天請教了實驗室裏的學長這個問題,問題大概是這樣:
1.Sim的設計者是如何知道NVIDIA公司GPU產品的底層實現,這個技術細節不是商業機密麼?
GPGPU-Sim是一個開放性的實驗平臺,它在仿真方面有很高的準確性,但是在具體細節方面,我們可以認爲他是合理的,但不一定是絕對準確的。因爲sim的設計中有NVIDIA的人,在文檔中有提到過。而且Sim所能使用的cuda還是4.0,所以NVIDIA可能會通過這個公佈一些老版本架構裏的細節,用於科研研究。
2.如果手上沒有GPU,可以裝這個仿真器來代替GPU跑cuda程序嗎?
這個仿真器確實可以很好模擬比較老的架構,但是因爲是串行模擬並行,所以一個在真實GPU上幾秒就跑完的程序,在性能模擬模式下,在Sim裏大概需要幾個小時甚至一天 。但是Sim的配置文件裏有一個選項(pure functional simulation:-gpgpu_ptx_sim_mode),可以只功能模擬,不輸出性能信息,那個還是比較快的。而且根據sim文檔中描述的,在GT200架構上的準確率是98.37%,在Fermi上的準確率是97.35%,已經很高了。
3.準確率是指什麼?計算結果的準確性還是性能模擬的吻合度?
IPC的準確率,應該是指性能模擬。計算結果準確性的話,在研究方面不突出……