[英]CUDA cudaMemCpy doesn't appear to copy despite CudaSuccess
我剛開始使用CUDA,這是我的第一個項目。 我已經搜索了這個問題,雖然我注意到其他人也有類似的問題,但是這些建議似乎都與我的特定問題無關,也沒有對我的情況有所幫助。
作為練習,我試圖使用CUDA編寫n體模擬。 在此階段,我對我的特定實現是否高效不感興趣,我只是在尋找可行的方法,以后可以對其進行改進。 一旦工作,我還需要稍后更新代碼,以使用我的SLI配置。
這是該過程的簡要概述:
(顯示尚未實現。我將在以后進行)
現在不用擔心加速度計算功能,這是更新功能:
__global__ void apply_acc(double* pos_x, double* pos_y, double* vel_x, double* vel_y, double* acc_x, double* acc_y, int N)
{
int i = threadIdx.x;
if (i < N);
{
vel_x[i] += acc_x[i];
vel_y[i] += acc_y[i];
pos_x[i] += vel_x[i];
pos_y[i] += vel_y[i];
}
}
這是main方法中的一些代碼:
cudaError t;
t = cudaMalloc(&d_pos_x, N * sizeof(double));
t = cudaMalloc(&d_pos_y, N * sizeof(double));
t = cudaMalloc(&d_vel_x, N * sizeof(double));
t = cudaMalloc(&d_vel_y, N * sizeof(double));
t = cudaMalloc(&d_acc_x, N * sizeof(double));
t = cudaMalloc(&d_acc_y, N * sizeof(double));
t = cudaMemcpy(d_pos_x, pos_x, N * sizeof(double), cudaMemcpyHostToDevice);
t = cudaMemcpy(d_pos_y, pos_y, N * sizeof(double), cudaMemcpyHostToDevice);
t = cudaMemcpy(d_vel_x, vel_x, N * sizeof(double), cudaMemcpyHostToDevice);
t = cudaMemcpy(d_vel_y, vel_y, N * sizeof(double), cudaMemcpyHostToDevice);
t = cudaMemcpy(d_acc_x, acc_x, N * sizeof(double), cudaMemcpyHostToDevice);
t = cudaMemcpy(d_acc_y, acc_y, N * sizeof(double), cudaMemcpyHostToDevice);
while (true)
{
calc_acc<<<1, N>>>(d_pos_x, d_pos_y, d_vel_x, d_vel_y, d_acc_x, d_acc_y, N);
apply_acc<<<1, N>>>(d_pos_x, d_pos_y, d_vel_x, d_vel_y, d_acc_x, d_acc_y, N);
t = cudaMemcpy(pos_x, d_pos_x, N * sizeof(double), cudaMemcpyDeviceToHost);
t = cudaMemcpy(pos_y, d_pos_y, N * sizeof(double), cudaMemcpyDeviceToHost);
std::cout << pos_x[0] << std::endl;
}
在每個循環中, cout
寫入相同的值,無論原始創建位置數組時將其設置為什么隨機值。 如果我將apply_acc
的代碼apply_acc
為類似以下內容:
__global__ void apply_acc(double* pos_x, double* pos_y, double* vel_x, double* vel_y, double* acc_x, double* acc_y, int N)
{
int i = threadIdx.x;
if (i < N);
{
pos_x[i] += 1.0;
pos_y[i] += 1.0;
}
}
那么它仍然會提供相同的值,因此不會調用apply_acc
或cudaMemcpy
不會將數據復制回去。
所有的cudaMalloc
和cudaMemcpy
調用都返回cudaScuccess
。
這里是完整代碼的PasteBin鏈接。 遵循起來應該很簡單,因為各種數組都有很多重復。
就像我說的那樣,我以前從未編寫過CUDA代碼,而是根據NVidia的#2 CUDA示例視頻編寫的,該人員編寫了並行數組附加代碼。 我不確定是否會有所不同,但是我將2x GTX970與最新的NVidia驅動程序和CUDA 7.0 RC一起使用,並且我選擇在安裝CUDA時不安裝捆綁的驅動程序,因為它們比我的要舊。
這行不通:
const int N = 100000;
...
calc_acc<<<1, N>>>(...);
apply_acc<<<1, N>>>(...);
內核啟動配置( <<<...>>>
)的第二個參數是每個塊的線程參數。 根據您的編譯方式,它限制為512或1024。 這些內核將不會啟動,並且需要通過使用正確的CUDA錯誤檢查來捕獲由此產生的錯誤類型。 僅查看后續CUDA API函數的返回值將不會表明存在這種類型的錯誤(這就是為什么您隨后看到cudaSuccess
原因)。
關於概念本身,我建議您進一步了解CUDA線程和塊層次結構 。 要啟動大量線程,您需要使用內核啟動配置的兩個參數(即前兩個參數中的一個都不為1)。 通常從性能角度來看也是建議的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.