CUDA:重新索引数组

时间:2014-08-12 22:33:38

标签: c++ arrays cuda indexing

在这个例子中,我有3个float数组,query_points [],initial_array []和final_array []。 query_points []中的值向下舍入并成为索引值,我想将initial_array []中这些索引处的数据复制到result_array []。

我遇到的问题是每几百个值,与正常工作的c ++代码相比,我得到了不同的值。我是CUDA的新手,不知道发生了什么。如果您能指出我的解决方案,请告诉我。谢谢!

CUDA代码:

int w = blockIdx.x * blockDim.x + threadIdx.x; // Col // width
int h = blockIdx.y * blockDim.y + threadIdx.y; // Row // height
int index = h*width+w;

if ((w < width) && (h < height)){
    int piece = floor(query_points[index]) - 1;
    int piece_index = h*width+piece;

    result_array[index] = initial_array[piece_index];
}

2 个答案:

答案 0 :(得分:1)

你在自己的评论中给出了答案:“我也认为这可能与我将相同的输入和输出数组传递给函数,尝试进行就地操作这一事实有关。”

您对症状的描述(仅偶尔发生,只在大型阵列上进行重新编码)也符合解释。

请注意,如果您想要完全并发,则无法始终防范竞争条件 - 您可能必须使用单独的输入和输出数组。合并排序和基数在处理时对中间阵列之间的乒乓进行排序。我认为没有人知道如何在没有O(N)辅助空间的情况下实现这些算法。

答案 1 :(得分:-1)

我没有编写代码来测试它,但我可以看到两个问题:

  1. 如果你正在使用floorf()函数而不是使用floorf()函数。我不认为这是原因,但显然这是更好的方法。
  2. 我能看到的主要问题是更微妙,或者我只是推测:floor()和floorf()分别返回float和double。所以,当你这样做时:

    floor(query_points [index]) - 1;

  3. 你所拥有的仍然是一个浮点数,可能小于你应该得到的实际积分值,因为精度损失。当您通过

    隐式将其强制转换为整数时
    int piece = floor(query_points[index]) - 1;
    

    你基本上截断小数部分并得到n-1,你认为你得到n。

    即使没有这种分析

    int piece = floor(query_points[index]) - 1;
    

    在这一行中,你是地板而不是截断,这基本上是相同的,所以你甚至不需要使用floor()或floorf()。