【问题标题】:Arm Mali T-624 STUCK EXECUTION TIME IN 12666 msArm Mali T-624 执行时间为 12666 毫秒
【发布时间】:2021-12-31 00:00:41
【问题描述】:

我在大学的论文中使用这个 GPU

我在这个东西上运行了很多不同的内核,执行时间停留在 12666.6689 毫秒,即使我有一个包含 88 条指令 * 100m 次迭代的循环。

__kernel void scalar_mult_add(__global  int * list)
{
    unsigned int x=38;
    unsigned int y=38;
    for(int i=0; i<1000000  ; i++){
        y=x*y;
        x=x+y;
    }
}

唯一可以增加执行时间的方法是在for循环语句中添加x!=0

__kernel void scalar_mult_add(__global  int * list)
{
    unsigned int x=38;
    unsigned int y=38;
    for(int i=0; i<1000000  && x!=0 ; i++){
        y=x*y;
        x=x+y;
    }
}

为什么这种事情总是发生?我无法理解:例如8800 万条指令与 100 万条指令的执行时间相同,尽管我没有那么多单元来像 100 万条指令那样同时执行这么大的内核。

为什么在循环中添加单个 x!=0 语句会使执行时间增加这么多,而在 for 循环中添加几项则不会?

【问题讨论】:

  • 代码有恒定的输入并且不产生输出,编译器优化器可能很容易消除大部分(如果不是全部)代码
  • 您检查过实际的编译器输出吗?你开启了什么优化级别?您拥有的第一个示例几乎可以被优化掉,因为循环并没有真正“做任何事情”。尝试查看实际的 ASM 输出。
  • 您似乎禁用了编译器优化。 If you observe the generated assembly(在 CPU 上,诚然,因为这是我方便的)你的两个函数都可以优化到 nothing。因为这两个函数都没有明显的效果。
  • 是的,我的 cpp 文件中有“-cl-opt-disable”。您会推荐使用另一个优化标志吗?我不需要内核的实际结果的原因是因为我不使用内核的结果,因为我只想验证 gpu 单元、管道深度并检查可用的单元(向量和标量)。我怎样才能让编译器不消除我没有效果的代码?
  • Mali 编译器没有禁用优化的选项。更改内核以保留输出,或在计算期间对循环值产生副作用。

标签: c++ arm opencl mali


【解决方案1】:

为什么在循环中添加单个 x!=0 语句会使执行时间增加?

在原始情况下,循环不做任何事情 - 不保留输出,也不将循环结果用于任何进一步的计算。正如上面的 cmets 所述,编译器可能只是优化了循环。

x != 0 添加到循环条件检查意味着循环结果被“使用”——您需要之前的迭代循环结果来确定是否继续迭代。代码仍然没有意义(没有输出),但编译器并不认为这是死代码,所以它留在里面。

但是,请注意 Mali-T624 具有 SIMD 向量单元。像这样编写一个依赖标量循环意味着您实际上是在扼杀编译器中的任何自动向量化。强烈建议使用 vec4 数据类型进行计算。

如果您想要一些基本的静态分析,您可能需要查看 Mali Offline Compiler,它可在 Arm Mobile Studio 中免费下载。请注意,编译 OpenCL 内核需要 macOS 或 Linux,但如果您使用的是 Windows,则可以在 WSL 下运行 Linux 二进制文件。

【讨论】:

  • 感谢您的回答@solidpixel,但我使用 opencl 标志 -cl-opt-disable。这个标志对我的死代码问题有帮助吗?(我的意思是它告诉编译器不要删除死代码)
  • 你完全没有办法说出来。依靠你无法为论文项目验证的东西似乎是不明智的。编写一个做一些明智的事情的内核,你会得到明智的结果。
猜你喜欢
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 2011-11-24
  • 2022-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多