0
我目前正在學習CUDA,現在我主要關注主機和設備吞吐量之間的內存拷貝。 這裏是一個小程序(請參見下面的註釋):CUDA |無法使用hostalloc獲得高吞吐量
int NX=1000;
int NY=800;
int size=NX*NY;
size*=sizeof(PREC);
int threadsperbloc=512;
int blockspergrid=ceil(NX*NY/threadsperbloc);
//Allocate and instanciate host arrays
PREC *h_a;
PREC *h_b;
h_a=new PREC[NX*NY];
h_b=new PREC[NX*NY];
for (int i=0;i<NX*NY;i++){
h_a[i]=i;
h_b[i]=i;
}
//Allocate device arrays and a paged-locked host array to fetch results
PREC *d_a=NULL;
PREC *d_b=NULL;
PREC *d_c=NULL;
PREC *dh_c=NULL;
CUDA_CHECK(cudaMalloc(&d_a,size));
CUDA_CHECK(cudaMalloc(&d_b,size));
CUDA_CHECK(cudaMalloc(&d_c,size));
CUDA_CHECK(cudaMemcpy(d_a, h_a, size, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaMemcpy(d_b, h_b, size, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaHostAlloc(&dh_c,size,cudaHostAllocDefault));
//A little addition vector addition on the device
vecadd<<<blockspergrid,threadsperbloc>>>(d_a, d_b, d_c, NX*NY);
//Repeating copies from device to page-locked host memory
for(int t=0;t<30;t++){
CUDA_CHECK(cudaMemcpy(dh_c,d_c,size,cudaMemcpyDeviceToHost));
}
cout<<"Check : "<<h_a[1000]<<" + "<< h_b[1000]<<" = "<<dh_c[1000]<<endl;
注:PREC是一個宏(浮在這種情況下)。只有一個流被使用(主要的)。在這種情況下,我不使用異步,這不是重點。 (我試過了,但吞吐量沒有變化)。
通過這個我認爲是正確的測試(並提供了正確的數值結果),Visual Profiler告訴我只有1.52 GB/s的吞吐量(帶有「關注」圖標),每次傳輸大約3MB(僅供參考)。但是使用NVIDIA bandWidthTest從SDK,它說
Device to Host Bandwidth, 1 Device(s)
PINNED Memory Transfers
Transfer Size (Bytes) Bandwidth(MB/s)
33554432 3177.5
我有一個3.0的計算能力,還想實現吞吐量的3.smth GB /秒。我檢查了一下bandWidthTest.cu,但我看不到我做的不同(他們使用的是MemcpyAsync,但正如我所說的,我也嘗試過沒有不同的結果)。 編輯:也許你已經看到,來自SDK的測試正在進行約33MB的傳輸。其實在10次。我試過30 * 3MB,10 * 12MB,但沒有變化。 那麼,我做錯了什麼?
我做了一個簡單的應用程序,你的代碼的關鍵帶寬部分,它是[這裏](http://pastebin.com/vk9SU2QU)。當我運行該代碼時,我得到的報告帶寬約爲6GB/s,這對於PCIE Gen2 x16鏈路是正確的(如果bandwidthTest報告爲3GB/s,我假設您在Gen1 x16鏈路或Gen2 x8鏈路上) 。當我在可視化剖析器(nvvp)中運行相同的代碼時,在右上角的「細節圖」選項卡中,它也報告最大,平均和最小吞吐量約爲6GB/s。所以我不清楚你爲什麼看到不同。你可以嘗試運行我的代碼並查看它報告的內容嗎? –
感謝您的評論羅伯特。我編譯並運行你的代碼(從終端,使用準無標誌編譯),它輸出帶寬= 4569.385254兆字節/秒,相當不錯!但是,當我在nvvp中運行使用您的代碼生成的可執行文件時,我也看到它僅限於1.54 GB/s,並且......等等!我重新編譯,執行:6 GB /秒!再次運行:3!再次運行:1.1 ..我錯過了什麼?設備(流0)應該被同步。我只是不明白 –
其他人正在使用帶寬。你是否在使用這款GPU顯示器?也許你應該給你的系統設置硬件和軟件的完整描述。嘗試運行一個副本循環(而不是30,而您需要更改bw calc中的乘數)並查看是否獲得更一致的結果。您的系統硬件電源管理也可能會根據活動動態更改PCIE鏈接寬度和/或速度。這可能會導致難以衡量或獲得一致的結果。 –