Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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 向量类型的全局数组解决方法_Cuda - Fatal编程技术网

Cuda 向量类型的全局数组解决方法

Cuda 向量类型的全局数组解决方法,cuda,Cuda,在CUDA中,我尝试使用由向量组成的数组(在我的例子中是int2)进行编译时优化,但我无法以干净的方式实现这一点。更具体地说,我正在研究一个使用两个常量数组c和w的问题。数组w由浮点数组成,数组c由int2组成。现在,由于这些数组是常量,我希望编译器执行编译时优化,从而有效地优化数组访问。例如,对于以下两个设备函数,编译器展开循环并通过直接将其替换为c和w值来优化阵列访问: __forceinline__ __device__ float someFunction1() { const in

在CUDA中,我尝试使用由向量组成的数组(在我的例子中是int2)进行编译时优化,但我无法以干净的方式实现这一点。更具体地说,我正在研究一个使用两个常量数组c和w的问题。数组w由浮点数组成,数组c由int2组成。现在,由于这些数组是常量,我希望编译器执行编译时优化,从而有效地优化数组访问。例如,对于以下两个设备函数,编译器展开循环并通过直接将其替换为c和w值来优化阵列访问:

__forceinline__ __device__ float someFunction1() {
  const int2  c[9] = {make_int2(0, 0), make_int2(1, 0), make_int2(0, 1), make_int2(-1, 0), make_int2(0, -1),
                      make_int2(1, 1), make_int2(-1, 1), make_int2(-1, -1), make_int2(1, -1)};
  const float w[9] = {4.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/36.0f, 1.0f/36.0f, 1.0f/36.0f, 1.0f/36.0f};
  #pragma unroll
  for (int i = 0; i < 9; ++i) {
    //Do something here, accessing c[i] and w[i]
  }
}

__forceinline__ __device__ float someFunction2() {
  const int2  c[9] = {make_int2(0, 0), make_int2(1, 0), make_int2(0, 1), make_int2(-1, 0), make_int2(0, -1),
                           make_int2(1, 1), make_int2(-1, 1), make_int2(-1, -1), make_int2(1, -1)};
  const float w[9] = {4.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/36.0f, 1.0f/36.0f, 1.0f/36.0f, 1.0f/36.0f};
  #pragma unroll
  for (int i = 0; i < 9; ++i) {
    //Do something here, accessing c[i] and w[i]
  }
}
\uuuuu forceinline\uuuuu设备\uuuuuuu浮点someFunction1(){
const int2 c[9]={make_int2(0,0),make_int2(1,0),make_int2(0,1),make_int2(-1,0),make_int2(0,-1),
make_int2(1,1),make_int2(-1,1),make_int2(-1,-1),make_int2(1,-1)};
常量浮点w[9]={4.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/36.0f,1.0f/36.0f,1.0f/36.0f};
#布拉格展开
对于(int i=0;i<9;++i){
//在这里做点什么,访问c[i]和w[i]
}
}
__forceinline\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu{
const int2 c[9]={make_int2(0,0),make_int2(1,0),make_int2(0,1),make_int2(-1,0),make_int2(0,-1),
make_int2(1,1),make_int2(-1,1),make_int2(-1,-1),make_int2(1,-1)};
常量浮点w[9]={4.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/36.0f,1.0f/36.0f,1.0f/36.0f};
#布拉格展开
对于(int i=0;i<9;++i){
//在这里做点什么,访问c[i]和w[i]
}
}
现在,问题是我不想在每个使用c和w的设备函数中连续声明c和w。我可以全局声明w,但不允许全局声明c,因为CUDA不允许我在全局变量中调用make_int2构造函数。也就是说,下面的程序给出错误“无法为设备上的非空构造函数或析构函数生成代码”:

//不允许这样声明数组c
__设备常数int2 c[9]={make_int2(0,0),make_int2(1,0),make_int2(0,1),make_int2(-1,0),make_int2(0,-1),
make_int2(1,1),make_int2(-1,1),make_int2(-1,-1),make_int2(1,-1)};
__设备常数浮点w[9]={4.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,1.0f/36.0f,1.0f/36.0f,1.0f/36.0f};
__forceinline\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu{
#布拉格展开
对于(int i=0;i<9;++i){
//在这里做点什么,访问c[i]和w[i]
}
}
我的问题是:如何防止在访问这些变量的每个函数中声明c和w,并且仍然有我想要的编译时优化?或者另外声明:是否有一个全局声明向量数组的解决方案


注意:我知道我可以将c和w存储在全局或常量内存中,但这不会给我编译时优化__常量内存在不定期访问时也可能出现问题。

我不知道这是否真的能够实现编译器优化方面的目标,但将指针从int转换为int似乎对我有效:

#include <stdio.h>

  __device__ const int  ci[16] = {0, 0, 1, 0, 0, 1, -1, 0, 0, -1, 1, 1, -1, 1, -1, -1};

  __device__ const int2 *c = (const int2 *)ci;

  __global__ void mykernel(){

  int2 temp = c[1];
  int2 temp1 = c[4];
  printf("c[1].x = %d\n", temp.x);
  printf("c[4].y = %d\n", temp1.y);
  }

int main(){

  mykernel<<<1,1>>>();
  cudaDeviceSynchronize();
  printf("Done\n");
  return 0;
}
#包括
__设备常数int ci[16]={0,0,1,0,0,1,-1,0,0,-1,1,1,-1,1,-1,1,-1};
__设备常数int2*c=(常数int2*)ci;
__全局_uu; void mykernel(){
int2温度=c[1];
int2 temp1=c[4];
printf(“c[1].x=%d\n”,temp.x);
printf(“c[4].y=%d\n”,temp1.y);
}
int main(){
mykernel();
cudaDeviceSynchronize();
printf(“完成”\n);
返回0;
}

请注意,
const
和不是一回事。您可以从
c
ci
的变量定义中删除
const
声明,但我认为在那里有助于编译器实现您的愿望。

是我还是您让我们回答一个循环相关问题?顺便问一下,在第二个代码示例中,您在全局内存中声明
c
,然后在N.B.中声明。之后,您在全局内存中声明您没有优化。如果在全局内存中没有优化声明,为什么要在第二个代码示例中这样做?
常量
内存在任何情况下都会比
全局
内存问题小,如果访问模式是不规则的,我会说。@KiaMorot:很抱歉混淆了“全局”术语。我的意思是,通常在全局内存中将数组声明为设备int2c[9],而不直接初始化它。在这种情况下,您稍后会初始化它,但是编译器可能不会执行编译时优化。另一方面,如果我声明一个数组并直接初始化它,编译器可能会执行常量折叠,这有效地优化了数组访问。@KiaMorot:至于关于_constant_uuuvs global的问题。是的,_constant_uu在任何情况下都比global快。我说这句话只是为了防止人们建议我使用_constant_内存来解决我的问题。使用--ptxas options=-v编译时,寄存器的用法与您的技巧几乎相同,这使我倾向于您的技巧似乎有效。遗憾的是,我目前的应用程序还没有准备好进行一个像样的基准测试,内存带宽有限,计算也不受限制。谢谢你展示这个好把戏。它确实需要PTX ISA 2.1版或更高版本。是的,我知道常数和常数之间的区别。
#include <stdio.h>

  __device__ const int  ci[16] = {0, 0, 1, 0, 0, 1, -1, 0, 0, -1, 1, 1, -1, 1, -1, -1};

  __device__ const int2 *c = (const int2 *)ci;

  __global__ void mykernel(){

  int2 temp = c[1];
  int2 temp1 = c[4];
  printf("c[1].x = %d\n", temp.x);
  printf("c[4].y = %d\n", temp1.y);
  }

int main(){

  mykernel<<<1,1>>>();
  cudaDeviceSynchronize();
  printf("Done\n");
  return 0;
}