之前有介绍怎么用cudaIpcGetMemHandle,cudaIpcOpenMemHandle来开发共享内存,遇到了CUDA 208(cudaErrorAlreadyMapped = 208)错误。由于CUDA代码不开源,只能自己摸索分析下。
首先cudaIpcOpenMemHandle的208错误不是必现的,程序运行一段时间,就会偶现。开始觉得是不是大量使用资源,导致资源不够用了。文档上说“If the memory handle has already been opened by the current context, the reference count on the handle is incremented by 1 and the existing device pointer is returned.”, 那就是在同一个进程,如果已经打开过一次,就会将引用加1,208可能是打开的时候有冲突。208怎么能快速重现?
static GMutex mutex;
void *func(void *ptr) {
//const char *msg = (const char *) ptr;
volatile shmStruct *shm = NULL;
shm = (volatile shmStruct *)ptr;
int frame_size = shm->data.frame_size;
//g_mutex_lock (&mutex);
cudaError_t err = cudaIpcOpenMemHandle(&ptr, *(cudaIpcMemHandle_t *)&shm->memHandle, cudaIpcMemLazyEnablePeerAccess);
if(err != 0)
printf("err:%d\n", err);
//g_mutex_unlock (&mutex);
//printf("thread quit\n");
return NULL;
}
cudaError_t err = cudaIpcOpenMemHandle(&ptr, *(cudaIpcMemHandle_t *)&shm->memHandle, cudaIpcMemLazyEnablePeerAccess);
if(err != 0)
printf("err:%d\n", err);
printf("100 open\n");
for(int i = 0; i < 1000; i++){
cudaError_t err = cudaIpcOpenMemHandle(&ptr, *(cudaIpcMemHandle_t *)&shm->memHandle, cudaIpcMemLazyEnablePeerAccess);
if(err != 0)
printf("err:%d\n", err);
}
如果使用多线程反复同时调用cudaIpcOpenMemHandle,程序就能很快重现208错误。那既然同时调用有冲突,那可以加个锁,如上注释部分。加了锁之后,208错误就不能重现了。