矩阵乘法的自动矢量化

时间:2017-04-05 23:28:45

标签: c gcc vectorization sse simd

我对SIMD很新,想要试着看看我是否可以让GCC为我做一个简单的动作。

所以我看了this post,想做或多或少做同样的事情。 (但在Linux 64bit上使用gcc 5.4.0,对于KabyLake处理器)

我基本上有这个功能:

/* m1 = N x M matrix, m2 = M x P matrix, m3 = N x P matrix & output */
void mmul(double **m1, double **m2, double **m3, int N, int M, int P)
{
    for (i = 0; i < N; i++)
        for (j = 0; j < P; j++)
        {
            double tmp = 0.0;

            for (k = 0; k < M; k++)
                tmp += m1[i][k] * m2[k][j];

            tmp = m3[i][j];
        }
    return m3;
}

我使用-O2 -ftree-vectorize -msse2 -ftree-vectorizer-verbose=5编译,但是我没有看到任何关于矢量化完成的消息。

如果有人能帮助我,那将非常感激。

1 个答案:

答案 0 :(得分:2)

您的命令中没有完成矢量化的消息!您可以使用-fopt-info-vec打开矢量化报告。但是,不要依赖它。编译器有时会说谎(它们会对它进行矢量化和报告但不使用它!)你可以改进它们!为此,你可以测量加速。首先,禁用矢量化并测量时间t1。然后启用并测量时间t2。加速度将是t1 / t2,如果它大于1,它说编译器改进了如果1没有改善,如果小于1它说编译器自动矢量化器毁了你!另一种方法是将-S添加到命令中,并在单独的.s文件中查看汇编代码。

注意:如果您想查看自动向量化功能添加-march=native并删除-msse2

UPDATE:当您使用NM等变量作为循环计数器时,您可能看不到矢量化。因此,您应该使用constants代替。根据我的经验,矩阵 - 矩阵乘法可以使用gcc 4.8, 5.4 and 6.2进行矢量化。其他编译器(例如clang-LLVMICCMSVC也会对其进行矢量化。如评论中所述,如果您使用doublefloat数据类型,则可能需要使用-ffast-math这是-Ofast优化级别中的已启用标记,表示您不需要高精度的结果(大部分时间都可以)。这是因为ompilers对于浮选点操作更加关注。