我正在进行几次cudamemset调用,以便将我的值设置为0,如下所示:
void allocateByte( char **gStoreR,const int byte){
char **cStoreR = (char **)malloc(N * sizeof(char*));
for( int i =0 ; i< N ; i++){
char *c;
cudaMalloc((void**)&c, byte*sizeof(char));
cudaMemset(c,0,byte);
cStoreR[i] = c;
}
cudaMemcpy(gStoreR, cStoreR, N * sizeof(char *), cudaMemcpyHostToDevice);
}
然而,事实证明这非常缓慢。 GPU上是否存在memset函数,因为从CPU调用它需要花费大量时间。此外,cudaMalloc((void **)&amp; c,byte * sizeof(char))是否自动设置c指向0的位。
答案 0 :(得分:4)
每个cudaMemset
调用都会启动一个内核,因此如果N
很大且byte
很小,那么你将有很多内核启动开销会降低代码速度。没有设备端memset
,因此解决方案是编写一个遍历分配的内核,并在一次启动中将存储器归零。
顺便说一句,我强烈建议不要在CUDA中使用数组结构。使用单个大块线性内存并将索引编入该内存,实现相同结果的速度要慢得多且复杂得多。在您的示例中,它会将代码缩减为单个cudaMalloc
调用和单个cudaMemset
调用。在设备端,指针间接(速度很慢)会被一些非常快的整数运算所取代。如果主机上的源材料是结构数组,我建议使用优秀的thrust::zip_iterator之类的东西将数据转换为设备上的GPU友好形式。