0

我在大学的论文中使用这个 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;
    }
}

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

__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 循环中添加几个语句却没有?

4

1 回答 1

0

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

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

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

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

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

于 2021-11-22T07:57:55.810 回答