将Intel -03转换为__M256D指令对__M512D

发布于 2025-02-12 19:30:35 字数 160 浏览 1 评论 0原文

将编写为256矢量化寄存器编写的代码使用(2019)Intel编译器具有O3优化级别的512个说明?

例如,在两个__M256D对象上操作是否会转换为蒙版__M512D对象的相同数量的操作,或者分组以最大程度地使用寄存器,在最佳情况下,操作总数降低了一个因子2?

拱门:骑士着陆

Will a code written for a 256 vectorization register will be compiled to use 512 instructions using the (2019) intel compiler with O3 level of optimization?

e.g. will operations on two __m256d objects be either converted to the same amount of operations over masked __m512d objects or grouped to make the most use out of the register, in the best case the total number of operations dropping by a factor 2?

arch: Knights Landing

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

药祭#氼 2025-02-19 19:30:35

不幸的是, no :编写用于使用AVX/AVX-2内在的代码不是由ICC重写的,因此请使用AVX-512(ICC 2019和ICC 2021)。没有指示融合。这是一个示例(请参阅 godbolt )。

#include <x86intrin.h>

void compute(double* restrict data, int size)
{
    __m256d cst1 = _mm256_set1_pd(23.42);
    __m256d cst2 = _mm256_set1_pd(815.0);
    __m256d v1 = _mm256_load_pd(data);
    __m256d v2 = _mm256_load_pd(data+4);
    __m256d v3 = _mm256_load_pd(data+8);
    __m256d v4 = _mm256_load_pd(data+12);
    v1 = _mm256_fmadd_pd(v1, cst1, cst2);
    v2 = _mm256_fmadd_pd(v2, cst1, cst2);
    v3 = _mm256_fmadd_pd(v3, cst1, cst2);
    v4 = _mm256_fmadd_pd(v4, cst1, cst2);
    _mm256_store_pd(data, v1);
    _mm256_store_pd(data+4, v2);
    _mm256_store_pd(data+8, v3);
    _mm256_store_pd(data+12, v4);
}

生成的代码:

compute:
        vmovupd   ymm0, YMMWORD PTR .L_2il0floatpacket.0[rip]   #5.20
        vmovupd   ymm1, YMMWORD PTR .L_2il0floatpacket.1[rip]   #6.20
        vmovupd   ymm2, YMMWORD PTR [rdi]                       #7.33
        vmovupd   ymm3, YMMWORD PTR [32+rdi]                    #8.33
        vmovupd   ymm4, YMMWORD PTR [64+rdi]                    #9.33
        vmovupd   ymm5, YMMWORD PTR [96+rdi]                    #10.33
        vfmadd213pd ymm2, ymm0, ymm1                            #11.10
        vfmadd213pd ymm3, ymm0, ymm1                            #12.10
        vfmadd213pd ymm4, ymm0, ymm1                            #13.10
        vfmadd213pd ymm5, ymm0, ymm1                            #14.10
        vmovupd   YMMWORD PTR [rdi], ymm2                       #15.21
        vmovupd   YMMWORD PTR [32+rdi], ymm3                    #16.21
        vmovupd   YMMWORD PTR [64+rdi], ymm4                    #17.21
        vmovupd   YMMWORD PTR [96+rdi], ymm5                    #18.21
        vzeroupper                                              #19.1
        ret                                                     #19.1

为ICC的两个版本生成相同的代码。

请注意,使用AVX-512不应始终以两倍的速度加快代码。例如,在Skylake SP(服务器端处理器)上,有2个AVX/AVX-2 SIMD单元可以融合以执行AVX-512指令,但Fusing不能改善吞吐量(假设SIMD单位是瓶颈)。但是,Skylake SP还支持不支持AVX/AVX-2(仅在某些处理器上可用)的可选其他512位SIMD单元。在这种情况下,AVX-512可以使您的代码更快两倍。

Unfortunately, no: a code written to use AVX/AVX-2 intrinsics is not rewritten by ICC so to use AVX-512 yet (with both ICC 2019 and ICC 2021). There is no instruction fusing. Here is an example (see on GodBolt).

#include <x86intrin.h>

void compute(double* restrict data, int size)
{
    __m256d cst1 = _mm256_set1_pd(23.42);
    __m256d cst2 = _mm256_set1_pd(815.0);
    __m256d v1 = _mm256_load_pd(data);
    __m256d v2 = _mm256_load_pd(data+4);
    __m256d v3 = _mm256_load_pd(data+8);
    __m256d v4 = _mm256_load_pd(data+12);
    v1 = _mm256_fmadd_pd(v1, cst1, cst2);
    v2 = _mm256_fmadd_pd(v2, cst1, cst2);
    v3 = _mm256_fmadd_pd(v3, cst1, cst2);
    v4 = _mm256_fmadd_pd(v4, cst1, cst2);
    _mm256_store_pd(data, v1);
    _mm256_store_pd(data+4, v2);
    _mm256_store_pd(data+8, v3);
    _mm256_store_pd(data+12, v4);
}

Generated code:

compute:
        vmovupd   ymm0, YMMWORD PTR .L_2il0floatpacket.0[rip]   #5.20
        vmovupd   ymm1, YMMWORD PTR .L_2il0floatpacket.1[rip]   #6.20
        vmovupd   ymm2, YMMWORD PTR [rdi]                       #7.33
        vmovupd   ymm3, YMMWORD PTR [32+rdi]                    #8.33
        vmovupd   ymm4, YMMWORD PTR [64+rdi]                    #9.33
        vmovupd   ymm5, YMMWORD PTR [96+rdi]                    #10.33
        vfmadd213pd ymm2, ymm0, ymm1                            #11.10
        vfmadd213pd ymm3, ymm0, ymm1                            #12.10
        vfmadd213pd ymm4, ymm0, ymm1                            #13.10
        vfmadd213pd ymm5, ymm0, ymm1                            #14.10
        vmovupd   YMMWORD PTR [rdi], ymm2                       #15.21
        vmovupd   YMMWORD PTR [32+rdi], ymm3                    #16.21
        vmovupd   YMMWORD PTR [64+rdi], ymm4                    #17.21
        vmovupd   YMMWORD PTR [96+rdi], ymm5                    #18.21
        vzeroupper                                              #19.1
        ret                                                     #19.1

The same code is generated for both version of ICC.

Note that using AVX-512 should not always speed up your code by a factor of two. For example, on Skylake SP (server-side processors) there is 2 AVX/AVX-2 SIMD units that can be fused to execute AVX-512 instructions but fusing does not improve throughput (assuming the SIMD units are the bottleneck). However, Skylake SP also supports an optional additional 512-bits SIMD units that does not support AVX/AVX-2 (only available on some processors). In this case, AVX-512 can make your code twice faster.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文