小编ove*_*yan的帖子

如何指示 gfortran 仅使用可分配数组的矢量化(最高可用 SIMD)指令来编译循环?

当 gfortran 对方程(例如 x = y*z )进行向量化时,编译器将仅使用向量寄存器(例如 YMM)和向量操作码,当且仅当编译器知道所有数据 (x,y,z) 都可以是加载到所述向量寄存器上。然而,如果编译器不知道是否所有数据都可以加载到寄存器中,它将生成冗余代码,以便可以操作剩余的数据。

此冗余代码通常不会使用最高可用的 SIMD 向量寄存器,并且会使可执行文件膨胀。我还没有进行广泛的测试,但常见的推理使我相信它可能会导致 ICACHE 缺失或阻止函数/子例程内联优化。

我想删除这个冗余代码,因为我知道我的所有数据 (x,y,z) 将完美地适合 YMM 向量寄存器。

我之前曾在这里更详细地描述过我的观察结果:https: //www.cfd-online.com/Forums/main/231759-fortran- assembly-how-remove-redundant-non-vectorized-code.html

不过,我想在这里举一些简单的例子来展示我的观点。

对于以下操作:x(:) = y*z其中x,y,z都是可分配数组,编译器不知道该操作是否可以完全矢量化,因为它不知道数组的长度是多少。如果 x,y,z 是整数数组并且长度是 8 的倍数,我们可以推断整个操作可以简单地使用 AVX2 向量化操作来完成。然而,由于数组长度在编译时未知,编译器必须生成可用于任意长度数组的冗余代码。

上帝螺栓链接:https://gcc.godbolt.org/z/1fdzK8

这是为该x(:) = y*z部分生成的程序集:

.L7:
        vmovdqu ymm1, YMMWORD PTR [r13+0+rax]
        vpmulld ymm0, ymm1, YMMWORD PTR [r12+rax]
        vmovdqu YMMWORD PTR [r14+rax], ymm0
        add     rax, 32
        cmp     rdx, rax
        jne     .L7
        mov     rdx, r15
        and     rdx, -8
        lea     rax, [rdx+1]
        cmp     rdx, …
Run Code Online (Sandbox Code Playgroud)

fortran simd gfortran avx2 intel-fortran

5
推荐指数
1
解决办法
542
查看次数

标签 统计

avx2 ×1

fortran ×1

gfortran ×1

intel-fortran ×1

simd ×1