Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CUDA多gpu:运行同一内核(双芯片设备)_Cuda_Multi Gpu - Fatal编程技术网

CUDA多gpu:运行同一内核(双芯片设备)

CUDA多gpu:运行同一内核(双芯片设备),cuda,multi-gpu,Cuda,Multi Gpu,我正在编写的代码必须在GTX690(双芯片)板上运行相同的内核。由于计算是可分离的,我不需要在设备之间进行数据交换,我只需要在CPU上合并结果。我了解如何在每个设备上运行代码,以及如何在每个设备的内存空间中提供I/o数据空间 我在尝试设置常量时遇到了问题,在两个设备上运行的内核都使用常量。我是否需要为每个设备制作一个阵列?如果是这样,我如何在内核中检查哪个设备正在运行,以便从数组中访问适当的常量 下面是我正在使用的一些代码。当我只使用一个芯片时(通过设置numDev=1),它可以正常工作,但不能

我正在编写的代码必须在GTX690(双芯片)板上运行相同的内核。由于计算是可分离的,我不需要在设备之间进行数据交换,我只需要在CPU上合并结果。我了解如何在每个设备上运行代码,以及如何在每个设备的内存空间中提供I/o数据空间

我在尝试设置常量时遇到了问题,在两个设备上运行的内核都使用常量。我是否需要为每个设备制作一个阵列?如果是这样,我如何在内核中检查哪个设备正在运行,以便从数组中访问适当的常量

下面是我正在使用的一些代码。当我只使用一个芯片时(通过设置
numDev=1
),它可以正常工作,但不能同时在两个芯片上工作

__constant__ float d_cellSizeZ;  
std::vector<int*> d_cell;  
.................  
bool Init(int cellsN_, float size_){  
  bool res = true;
  if(cudaSuccess != cudaGetDeviceCount(&numDev))  
    return false;  
  //numDev = 1;  
  d_cl.resize(numDev);  
  for(int i = 0; i < numDev; ++i){  
    res &= (cudaSuccess == cudaSetDevice(i));  
    if(!res)  
      break;  
    res &= (cudaSuccess == cudaMalloc((void**)&d_cell[i], cellsN_*sizef(int)));  
  };  
  res &= (cudaSuccess == cudaMemcpyToSymbol(d_cellSizeZ, &size_, sizeof(float)));  
  if(!res)  
    Cleanup();  
  return res;  
}
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
std::载体d_细胞;
.................  
bool Init(int cellsN,float size){
bool res=真;
if(cudaSuccess!=cudaGetDeviceCount(&numDev))
返回false;
//numDev=1;
d_cl.调整大小(numDev);
对于(int i=0;i
在内核中,我只使用
d_cellSizeZ
常量。那么,我应该如何为每个设备设置一个常量,以便从同一个内核中很好地使用它们呢


另一个问题是:如果我尝试在设备之间交换数据,它会通过PCI总线还是在双芯片板上存在一些内部路径?

您只是在最后一个设备上初始化
d_cellSizeZ
,因此在其他设备上它将是未定义的。您需要在每个设备上初始化
d_cellSizeZ
,最简单的方法是在循环内进行初始化,正如Greg在评论中建议的那样:

for(int i = 0; i < numDev; ++i)
{  
    checkCudaErrors(cudaSetDevice(i));
    checkCudaErrors(cudaMalloc((void**)&d_cell[i], cellsN_*sizef(int)));
    checkCudaErrors(cudaMemcpyToSymbol(d_cellSizeZ, &size_, sizeof(float)));
};
for(int i=0;i

重复使用d_cellSizeZ符号确实有点奇怪。幕后有一点小聪明,但本质上是
cudaMemcpyToSymbol()
函数查找当前活动设备上的符号,因此每次都复制到正确的设备。

每个设备都有不同的CUcontext。调用CUDASETDEVIECE将主机线程切换为当前活动的CUcontext。积云模块按照CUcontext加载。目前您仅在设备[numDev-1]上设置符号。尝试将CUDAMEMCPITOSYMBOL移动到for循环中。这会将结果复制到每个CUContext内存空间。是的,这就是我的想法,但困扰我的是,如果常量是类似smth的指针,那么对它的第二次调用将覆盖以前设备的值集,或者它只是某种名称,因此,在每个设备中,它将对应于恒定内存中自己的指针?不幸的是,关于多GPU的信息太少了,而且大部分与专业的多特斯拉系统有关。如果您能提供一些关于使用双芯片设备的文档/示例,我将不胜感激:)