拷貝global memory,cudaMemcpyToSymbol 和cudaMemcpy函數是否有區別

這是今天在羣裏有人問了這麼一個問題
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的準確率,應該是指性能模擬。計算結果準確性的話,在研究方面不突出……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章