代码之家  ›  专栏  ›  技术社区  ›  Morten Christiansen

库达记忆障碍

  •  5
  • Morten Christiansen  · 技术社区  · 17 年前

    我有一个CUDA内核,我正在编译成一个没有任何特殊标志的CUBIN文件:

    nvcc text.cu -cubin
    

    它编译了以下消息:

    建议:假设全局内存空间,无法判断指针指向什么。

    以及对某个临时cpp文件中一行的引用。我可以通过评论一些对我来说毫无意义的看似武断的代码来实现这一点。

    内核如下:

    __global__ void string_search(char** texts, int* lengths, char* symbol, int* matches, int symbolLength)
    {
        int localMatches = 0;
        int blockId = blockIdx.x + blockIdx.y * gridDim.x;
        int threadId = threadIdx.x + threadIdx.y * blockDim.x;
        int blockThreads = blockDim.x * blockDim.y;
    
        __shared__ int localMatchCounts[32];
    
        bool breaking = false;
        for(int i = 0; i < (lengths[blockId] - (symbolLength - 1)); i += blockThreads)
        {
            if(texts[blockId][i] == symbol[0])
            {
                for(int j = 1; j < symbolLength; j++)
                {
                    if(texts[blockId][i + j] != symbol[j])
                    {
                        breaking = true;
                        break;
                    }
                }
                if (breaking) continue;
                localMatches++;
            }
        }
    
        localMatchCounts[threadId] = localMatches;
    
        __syncthreads();
    
        if(threadId == 0)
        {
            int sum = 0;
            for(int i = 0; i < 32; i++)
            {
                sum += localMatchCounts[i];
            }
            matches[blockId] = sum;
        }
    }
    

    如果我换线

    localMatchCounts[threadId] = localMatches;
    

    在这条线的第一个for循环之后

    localMatchCounts[threadId] = 5;
    

    它编译时没有通知。这也可以通过注释行上方的循环中看似随机的部分来实现。我还尝试用普通数组替换本地内存数组,但没有效果。有人能告诉我是什么问题吗?

    这个系统是vista 64位的,就其价值而言。

    编辑:我修复了代码,这样它实际上可以工作,尽管它仍然会生成编译器的通知。似乎警告并不是一个问题,至少在正确性方面(它可能会影响性能)。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Danny Varod    16 年前

    像char**这样的指针数组在内核中是有问题的,因为内核无法访问主机的内存。
    最好分配一个 连续的 缓冲区并以允许并行访问的方式对其进行划分。
    在本例中,我将定义一个1d数组,其中包含一个接一个的所有字符串和另一个1d数组,大小为2*个字符串,其中包含第一个数组中每个字符串的偏移量及其长度:

    例如-内核准备:

    char* buffer = st[0] + st[1] + st[2] + ....;
    int* metadata = new int[numberOfStrings * 2];
    int lastpos = 0;
    for (int cnt = 0; cnt < 2* numberOfStrings; cnt+=2)
    {
        metadata[cnt] = lastpos;
        lastpos += length(st[cnt]);
        metadata[cnt] = length(st[cnt]);
    }
    
    内核中:
    currentIndex = threadId + blockId * numberOfBlocks;
    char* currentString = buffer + metadata[2 * currentIndex];
    int currentStringLength = metadata[2 * currentIndex + 1];
    
        2
  •  0
  •   Morten Christiansen    17 年前

    问题似乎与char**参数有关。把这个转换成char*解决了这个警告,所以我怀疑cuda可能在这种数据形式上有问题。也许在这种情况下,CUDA更喜欢使用特定的CUDA二维数组。