0

在 OpenCL 中查找数组最大值的简单任务遇到了麻烦。

__kernel void ndft(/* lots of stuff*/)
{
    size_t thread_id = get_global_id(0); // thread_id = [0 .. spectrum_size[

    /* MATH MAGIC */

    // Now I have    float spectrum_abs[spectrum_size]    and
    // I want the maximum as well as the index holding the maximum

    barrier();
    // this is the old, sequential code:
    if (*current_max_value < spectrum_abs[i])
    {
        *current_max_value = spectrum_abs[i];
        *current_max_freq = i;
    }
}

现在我可以if (thread_id == 0)像在单核系统上那样添加和循环整个事情,但是由于性能一个关键问题(否则我不会在 GPU 上进行频谱计算),有没有更快的方法来做到这一点?

在上面的内核结束时返回 CPU 不是一种选择,因为内核实际上在那之后继续。

4

1 回答 1

2

您将需要编写并行归约。将您的“大”数组分成小块(单个工作组可以有效处理的大小)并计算每个小块。

反复执行此操作(涉及主机和设备代码),直到您只剩下一组最小值/最大值。

请注意,您可能需要编写一个单独的内核来执行此操作,除非当前的工作分发适用于这部分内核(请参阅我上面的问题)。

如果您当前的工作分配适合,另一种方法是找到每个工作组内的最小最大值并将其写入全局内存中的缓冲区(索引 = local_id)。在barrier()之后,只需让运行在thread_id == 0 上的内核循环遍历减少的结果并找到其中的最大值。这不是最佳解决方案,但可能适合您当前的内核。

于 2012-05-03T21:05:48.500 回答