unified memory 在被 kernel 函數訪問的時候,如果同事被 host 函數訪問,那麼host 得到的結果可能是錯誤的,測試程序如下
#include <cuda_runtime.h>
#include <cassert>
__global__ void umem_test(int* cnt){
atomicAdd(cnt,1);
}
int main(){
int *cnt;
assert(cudaMallocManaged(&cnt,sizeof(*cnt))==cudaSuccess);
for(int i=0;i<1000;++i){
*cnt = 0;
umem_test<<<128,128>>>(cnt);
assert(*cnt==128*128);
}
return 0;
}
unified memory,如果此時正被kernel
使用,那麼在host
訪問時並不觸發cudaMemcpy
把上述程序改成一下形式,結果是正確的
#include <cuda_runtime.h>
#include <cassert>
__global__ void umem_test(int* cnt){
atomicAdd(cnt,1);
}
int main(){
int *cnt;
assert(cudaMallocManaged(&cnt,sizeof(*cnt))==cudaSuccess);
for(int i=0;i<1000;++i){
*cnt = 0;
umem_test<<<128,128>>>(cnt);
int resutl;
cudaMemcpy(&resutl,cnt,sizeof(resutl),cudaMemcpyDeviceToHost);
assert(*cnt==128*128);
}
return 0;
}
新插入的cudaMemcpy
和umem_test
都是在默認的stream
上執行的,而且cudaMemcpy
是同步操作,所以必須等待umem_test
執行完成才能執行,此時訪問*cnt
時,umem_test
已經完成,所示此時能夠得到正確結果