Variables cuda:为设备内存使用全局变量

Variables cuda:为设备内存使用全局变量,variables,memory,cuda,global,Variables,Memory,Cuda,Global,我有一个关于如何在cuda代码中使用适当变量的问题。我的程序有很多数组,需要在不同的函数中访问它们,我希望避免传递它们,并且希望使用全局变量和二维mallocpitch数组,而不是平坦的一维数组。所以,我在想这样的事情: __device__ double * dataPtr ; __device__ size_t dataPitch; .... int main() { double * dataPtrLoc; size_t dataPitchLoc; cudaMallocPitch( (v

我有一个关于如何在cuda代码中使用适当变量的问题。我的程序有很多数组,需要在不同的函数中访问它们,我希望避免传递它们,并且希望使用全局变量和二维mallocpitch数组,而不是平坦的一维数组。所以,我在想这样的事情:

__device__ double * dataPtr ;
__device__ size_t dataPitch;
....
int main()
{
 double * dataPtrLoc; size_t dataPitchLoc;
cudaMallocPitch( (void**) &dataPtrLoc, &dataPitchLoc, width*sizeof(double), height);
cudaMemcpyToSymbol(dataPtr, &dataPtrLoc, sizeof(dataPtrLoc));
cudaMemcpyToSymbol(dataPitch, &dataPitchLoc, sizeof(dataPitchLoc));
...
}
它看起来像是一种获取全局2D设备数据的好方法吗?你能提出建议吗

编辑:我制作了这个程序,它编译和运行良好:

#include <stdio.h>
__device__ int *d_gridPtr;
__device__ size_t d_gridPitch;

__device__ int valij(int ii, int jj)
{
  int* row = (int*)((char*)d_gridPtr + ii * d_gridPitch);
  return (row[jj]);
}

__global__ void printval()
{
  int val0, val1, val2, val3;
  val0= valij(0,0);
  val1= valij(0,1);
  val2= valij(1,0);
  val3= valij(1,1);
  printf("%d %d %d %d \n", val0, val1, val2, val3);
}

int main()
{
  size_t d_gridPitchLoc;
  int * d_gridPtrLoc;  
  cudaMallocPitch((void**)&d_gridPtrLoc, &d_gridPitchLoc, 2 * sizeof(int), 2);
  cudaMemcpyToSymbol(d_gridPtr, & d_gridPtrLoc, sizeof(d_gridPtrLoc));
  cudaMemcpyToSymbol(d_gridPitch, &d_gridPitchLoc, sizeof(float));

  int h_mem[2*2]={0,1,100,4};  
  size_t hostpitch = 2* sizeof(int);
  cudaMemcpy2D(d_gridPtrLoc,d_gridPitchLoc,h_mem,hostpitch,2*sizeof(int),2,cudaMemcpyHostToDevice );

  printval<<<1,1>>> ();
  cudaDeviceReset();  
}
#包括
__设备uuu int*d_gridPtr;
__设备尺寸和网格间距;
__设备_uujint valij(int ii,int jj)
{
int*行=(int*)((char*)d_gridPtr+ii*d_gridPitch);
返回(行[jj]);
}
__全局_uu; void printval()
{
int val0,val1,val2,val3;
val0=valij(0,0);
val1=valij(0,1);
val2=valij(1,0);
val3=valij(1,1);
printf(“%d%d%d%d\n”,val0,val1,val2,val3);
}
int main()
{
尺寸和尺寸;
int*d_gridPtrLoc;
cudaMallocPitch((void**)和d_gridPtrLoc和d_gridPitchLoc,2*sizeof(int),2);
cudaMemcpyToSymbol(d_gridPtr和d_gridPtrLoc,sizeof(d_gridPtrLoc));
cudaMemcpyToSymbol(d_gridPitch,&d_gridPitchLoc,sizeof(float));
int h_mem[2*2]={0,1100,4};
尺寸=2*sizeof(int);
cudaMemcpy2D(d_gridPtrLoc,d_gridPitchLoc,h_mem,hostpitch,2*sizeof(int),2,cudamemcpyhostodevice);
printval();
cudaDeviceReset();
}

< /代码> 如果一个翘曲或块的所有线程同时访问相同的只读全局内存地址(例如数组索引),则考虑将只读全局数据存储在<代码>如果写入数据,则不能使用
\uuuuu常量\uuuu


如果您的数组是只读的,并且您的访问模式具有强的2D局部性(在一个扭曲和/或块内),考虑使用纹理代替.< /p> ,如果一个翘曲或块的所有线程同时访问相同的只读全局内存地址(例如数组索引),然后考虑将只读全局数据存储在<代码>如果写入数据,则不能使用

\uuuuu常量\uuuu


如果您的数组是只读的,并且您的访问模式具有强的2D局部性(在扭曲和/或块内),请考虑使用纹理代替。

该代码不能工作。但对于这类事情,常量内存更有意义。无论数据是常量还是无关数据,您只是将指向全局内存数据的指针存储在常量内存中,而不是数据本身。这就是内核参数在费米GPU中的实现方式。我的数据不是常数。我记得读过一篇文章,恒定内存不一定是恒定的,只是缓存的全局内存(虽然不确定)。那么,您是否仍然认为,常量内存会起作用?那么,您是否建议使用_uuu设备_uuu常量_uuuuuu双*数据ptr并将内存符号复制到其中?在CUDA中将2D数据保持为2D可以提高性能,特别是在mem访问中存在空间局部性的情况下(在两个维度上,编译器都会明显看到合并等)。另外,如果您的数组适合于固定设备内存,则按如下方式声明:
\uuuuuu constant\uuuuuu\uuuuuu device\uuuuuuu\int dMyContantArray[1024]该代码不起作用-复制到dataPtr是错误的。但对于这类事情,常量内存更有意义。无论数据是常量还是无关数据,您只是将指向全局内存数据的指针存储在常量内存中,而不是数据本身。这就是内核参数在费米GPU中的实现方式。我的数据不是常数。我记得读过一篇文章,恒定内存不一定是恒定的,只是缓存的全局内存(虽然不确定)。那么,您是否仍然认为,常量内存会起作用?那么,您是否建议使用_uuu设备_uuu常量_uuuuuu双*数据ptr并将内存符号复制到其中?在CUDA中将2D数据保持为2D可以提高性能,特别是在mem访问中存在空间局部性的情况下(在两个维度上,编译器都会明显看到合并等)。另外,如果您的数组适合于固定设备内存,则按如下方式声明:
\uuuuuu constant\uuuuuu\uuuuuu device\uuuuuuu\int dMyContantArray[1024]