【问题标题】:CUDA: reindexing arraysCUDA:重新索引数组
【发布时间】:2014-10-06 03:57:31
【问题描述】:

在这个例子中,我有 3 个浮点数组,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];
}

【问题讨论】:

  • 请提供一个简短、完整的可编译代码,用于演示问题/不匹配。 SO 期望这一点:“寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题的问题声明对其他读者没有用。请参阅:How to create a Minimal, Complete, and Verifiable example."。您是否使用 cuda-memcheck 运行过您的代码?
  • @RobertCrovella 我不确定如何创建一个最小的示例,因为它需要大型数组才能发生错误。该代码在最小数组上运行良好。 Cuda-memcheck 显示 0 个错误。奇怪的是,在我重新启动系统后,问题就停止了,现在似乎工作正常,尽管我仍然对其可靠性持怀疑态度。我还认为这可能与我将相同的输入和输出数组传递给函数,试图进行就地操作有关。
  • “我还认为这可能与我将相同的输入和输出数组传递给函数,试图进行就地操作有关。”是的,这可能是一个问题,而且从您发布的代码或您的问题/描述中都看不出来,这当然听起来像是 3 个数组是不同的。提供一个完整的代码可以说明你实际上是在原地做事。如果您无法/不愿意提供完整的代码,我认为您的问题只会引发很多猜测,并且不适合 SO。

标签: c++ arrays cuda indexing


【解决方案1】:

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

您对症状的描述(它只是偶尔发生,并且只在大型阵列上重现)也符合解释。

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

【讨论】:

    【解决方案2】:

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

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

      楼层(query_points[index]) - 1;

    你所拥有的仍然是一个浮点数,并且可能小于由于精度损失而应该得到的实际整数值。当您通过

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

    你基本上截断了小数部分并在你认为你得到 n 的地方得到 n-1。

    即使没有这个分析

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

    在这一行中,你是地板和截断,它们本质上是一样的,所以你甚至不需要使用 floor() 或 floorf()。

    【讨论】:

    • 对于 x 的什么值, floor(x) 返回一个“小于您应该得到的实际整数值”的值?或者,如果您愿意,使用给定的代码行int piece = floor(query_points[index]) - 1;,您能否为右侧的变量提供任何数值,以说明获得的值“小于您应该得到的实际整数值,因为精度损失”? floor() 返回双倍数量。一个double数量可以精确表示的整数范围大于int可以表示的整数范围。
    • 感谢您的输入,如果我看到问题再次发生,我将调整我的代码以使用 floorf 并尝试转换为 int。我不确定这是否是主要问题,因为代码可能有 500 个条目的正确值,然后大约 100 个不正确,或多或少以该模式重复(尽管不完全正常)。
    猜你喜欢
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 2021-12-22
    • 2021-02-05
    • 2012-06-28
    • 2017-04-08
    • 2014-03-16
    相关资源
    最近更新 更多