Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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
C++ CUDA内核中的While循环失败_C++_Cuda - Fatal编程技术网

C++ CUDA内核中的While循环失败

C++ CUDA内核中的While循环失败,c++,cuda,C++,Cuda,我用GPU做一些文字处理的计算。 最初,我使用一个块(500个线程)来处理一个字。 要处理100个字,我必须在主函数中循环内核函数100次 for (int i=0; i<100; i++) kernel <<< 1, 500 >>> (length_of_word); 现在我想同时处理所有100个单词 每个块仍将有500个线程,并处理一个字(每个块) dev_totalwordarray:存储单词的所有字符(一个接一个) dev_lengt

我用GPU做一些文字处理的计算。 最初,我使用一个块(500个线程)来处理一个字。 要处理100个字,我必须在主函数中循环内核函数100次

for (int i=0; i<100; i++)
    kernel <<< 1, 500 >>> (length_of_word); 
现在我想同时处理所有100个单词

每个块仍将有500个线程,并处理一个字(每个块)

dev_totalwordarray:存储单词的所有字符(一个接一个)

dev_length_数组:存储每个单词的长度

dev_accu_length:存储单词的累计长度(之前所有单词的总字符数)

dev_salt_是一个大小为500的数组,存储无符号整数

因此,在我的主要职能中

   kernel2 <<< 100, 500 >>> (dev_totalwordarray, dev_length_array, dev_accu_length, dev_salt_);
我的函数内核现在如下所示:

__global__ void kernel (int *dev_length)
{
   int length = *dev_length;
   while (length > 4)
   {   //do something;
          length -=4;
   }
}
__global__ void kernel2 (char* dev_totalwordarray, int *dev_length_array, int* dev_accu_length, unsigned int* dev_salt_)
{

  tid = threadIdx.x + blockIdx.x * blockDim.x;
  unsigned int hash[N];

  int length = dev_length_array[blockIdx.x];

   while (tid < 50000)
   {
        const char* itr = &(dev_totalwordarray[dev_accu_length[blockIdx.x]]);
        hash[tid] = dev_salt_[threadIdx.x];
        unsigned int loop = 0;

        while (length > 4)
        {   const unsigned int& i1 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
            const unsigned int& i2 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
            hash[tid] ^= (hash[tid] <<  7) ^  i1 * (hash[tid] >> 3) ^ (~((hash[tid] << 11) + (i2 ^ (hash[tid] >> 5))));
            length -=4;
        }
        tid += blockDim.x * gridDim.x;
   }
}
\uuuuu全局\uuuuuu无效内核2(char*dev\u totalwordarray,int*dev\u length\u array,int*dev\u累计长度,无符号int*dev\u salt\u2)
{
tid=线程IDX.x+块IDX.x*块DIM.x;
无符号整数散列[N];
int length=dev_length_数组[blockIdx.x];
而(tid<50000)
{
const char*itr=&(dev_totalwordarray[dev_accu_length[blockIdx.x]];
hash[tid]=dev_salt[threadIdx.x];
无符号整数循环=0;
而(长度>4)
{const unsigned int&i1=*(reinterpret_cast(itr));itr+=sizeof(unsigned int);
常量unsigned int&i2=*(重新解释强制转换(itr));itr+=sizeof(unsigned int);
hash[tid]^=(hash[tid]>3)^(~(hash[tid]>5));
长度-=4;
}
tid+=blockDim.x*gridDim.x;
}
}
然而,内核2似乎根本不起作用

似乎是
而(长度>4)
导致了这种情况


有人知道为什么吗?谢谢。

我不确定while是否是罪魁祸首,但我发现您的代码中没有什么让我担心的东西:

  • 您的内核不产生任何输出。优化器很可能会检测到这一点,并将其转换为空内核
  • 在几乎任何情况下,您都不希望为每个线程分配数组。这将消耗大量内存。您的
    hash[N]
    表将按线程分配,并在内核末尾丢弃。如果
    N
    很大(然后乘以线程总数),您可能会耗尽GPU内存。更不用说,访问
    散列
    几乎和访问全局内存一样慢
  • 块中的所有线程将具有相同的
    itr
    值。这是有意的吗
  • 每个线程只初始化自己的
    哈希表副本中的一个字段
  • 我看到
    hash[tid]
    其中
    tid
    是一个全局索引。请注意,即使将
    哈希设置为全局,也可能会遇到并发问题。并非网格中的所有块都将同时运行。虽然一个块将初始化
    散列的一部分,但另一个块甚至可能不会启动
    
把//do something的代码放在那里,或者你只有这个?do//something的代码不使用可变长度。编辑问题并把它放在那里:)看起来很好。把//do something in case抱歉,N被全局定义为100*500。实际上,我的内核函数接收到的参数比我发布的要多。它将接收另一个指向哈希表的指针。所以我实际上想要我的内核做的是:1。每个线程计算一个散列值。2.每个块将计算一个字(一个字将有500个散列值)。3.哈希表(大小50000)将用所有值更新,然后我将更新后的哈希表复制回cpu。你能建议我如何修改代码吗?谢谢。我刚刚意识到每个线程只修改一个单元格:
hash[tid]
-这是预期的行为吗?另外-来自同一块的所有线程将从
dev\u totalwordarray
读取完全相同的内容。因此,
hash[tid]
中的输出将只因
dev_salt
的内容不同而不同;每个线程将处理整个单词。是的,你是对的。每个线程将处理整个单词,来自同一块的线程将处理同一个单词。如果这是您想要的,那么它应该可以工作。“根本不起作用”背后隐藏着什么?发射失败?输出错误。。。。编译时没有错误,但内核似乎没有被处理。我试着在while(tid<50000)中放入printf行,但没有打印任何内容(除非while(长度>4)被注释掉)。这就是为什么我认为(长度>4)是问题的主要原因。
    int* dev_array_of_word_length;
    HANDLE_ERROR( cudaMalloc( (void**)&dev_array_of_word_length, 100 * sizeof(int) ) );
    HANDLE_ERROR( cudaMemcpy( dev_array_of_word_length, actualwordlength2, 100 * sizeof(int),
__global__ void kernel2 (char* dev_totalwordarray, int *dev_length_array, int* dev_accu_length, unsigned int* dev_salt_)
{

  tid = threadIdx.x + blockIdx.x * blockDim.x;
  unsigned int hash[N];

  int length = dev_length_array[blockIdx.x];

   while (tid < 50000)
   {
        const char* itr = &(dev_totalwordarray[dev_accu_length[blockIdx.x]]);
        hash[tid] = dev_salt_[threadIdx.x];
        unsigned int loop = 0;

        while (length > 4)
        {   const unsigned int& i1 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
            const unsigned int& i2 = *(reinterpret_cast<const unsigned int*>(itr)); itr += sizeof(unsigned int);
            hash[tid] ^= (hash[tid] <<  7) ^  i1 * (hash[tid] >> 3) ^ (~((hash[tid] << 11) + (i2 ^ (hash[tid] >> 5))));
            length -=4;
        }
        tid += blockDim.x * gridDim.x;
   }
}