【问题标题】:AMD OpenCL C Compiler notes dead and deleted loops which shouldn't be dead and deletedAMD OpenCL C 编译器记录了不应该死和删除的死循环和删除循环
【发布时间】:2016-02-23 11:05:06
【问题描述】:

我在我的 OpenCl 内核中执行了以下循环:

__kernel void kernelA(/* many parameters */)
{
    /*  Prefetching code and other stuff
     *  ...
     *  ...
     */

    float2 valueA = 0.0f;

    #pragma unroll                              //<----- line X
    for(unsigned int i = 0; i < MAX_A; i++)     // MAX_A > 0
    {
        #pragma unroll
        for(unsigned int j = 0; j < MAX_B; j++) // MAX_B > 0
            valueA += arrayA[(i * MAX_A) + j];
    }

    /*
     *  Code that uses the result saved to valueA
     */
}

可以清楚地看到,循环将汇总 arrayA 中包含的值。现在我想试试#pragma unroll,看看循环执行和展开执行之间是否存在性能差异。

但是当我编译内核时,编译器注释LOOP UNROLL: pragma unroll (line X) ignored because this loop is dead and deleted.我不明白那个信息,因为循环中的代码肯定会执行。 MAX_A 和 MAX_B 肯定大于零,并且保存到 valueA 的和也在循环后使用。

我在代码的其他地方有相同的结构,这个位置也用上面的注释标记。

我使用的编译器是APP SDK提供的AMD OpenCL C编译器。

【问题讨论】:

  • 如果arrayA 从不改变它的值,并且MAX_AMAX_B 是常量(我猜是这样),那么编译器可能会在编译时“执行”循环产生一个常量值在valueA
  • 如果你能粘贴代码的objdump会很有帮助
  • 如果您希望我们跟踪正在发生的事情,您应该粘贴所有代码。就编译器所做的事情而言,一行代码就可以发挥作用。还要记住,不向输出数组输出任何内容的内核将始终被简化为空内核。
  • 对不起,我的回答迟了。由于另一个来源是非常特定于应用程序的,并且将进入专利,我无法发布更多信息。但是@DarkZeros 的回答让我找到了解决方案。我忘了填写内核的输出,所以编译器优化了所有内容。
  • 这就是为什么创建MCVE 很重要。在您的情况下,您应该只使用内核中发布的代码来设置一个新项目。

标签: opencl gpgpu pyopencl opencl.net


【解决方案1】:

@DarkZeroes 的评论是这个问题的解决方案。没有指令将结果放入内核的输出数组,因此上面的代码和所有依赖于它的代码都被编译器优化掉了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多