C++ 铿锵++/g++;未对Aarch64上的代码进行矢量化

C++ 铿锵++/g++;未对Aarch64上的代码进行矢量化,c++,arm,neon,C++,Arm,Neon,我有一个四核Cortex-A57的SBC,我正在尝试使用编译器自动矢量化来测试Neon。对于Ubuntu 18.04上的clang++(5.0.1-4)和g++(7.4.0),下面非常简单的代码没有矢量化(即,它在任何时候都不使用v寄存器): 在进行实际计算的同一个函数中生成输入 问:那么编译器在-o3下做什么 答:它在构建时进行计算,并将结果存储在某种LUT中。(.LC0) 您应该初始化外部函数中的输入,最好是在不同的文件中,以避免编译器进行这种“构建时数学”欺骗 0=0.0f=0.0f*2.

我有一个四核Cortex-A57的SBC,我正在尝试使用编译器自动矢量化来测试Neon。对于Ubuntu 18.04上的clang++(5.0.1-4)和g++(7.4.0),下面非常简单的代码没有矢量化(即,它在任何时候都不使用v寄存器):


在进行实际计算的同一个函数中生成输入

问:那么编译器在
-o3
下做什么

答:它在构建时进行计算,并将结果存储在某种LUT中。(
.LC0

您应该初始化外部函数中的输入,最好是在不同的文件中,以避免编译器进行这种“构建时数学”欺骗

0=0.0f=0.0f*2.0f*0.0f
1073741824=2.0f=1.0f*2.0f*1.0f
1090519040=8.0f=2.0f*2.0f*2.0f

1099956224=18.0f=3.0f*2.0f*3.0f

您可以在执行实际数学运算的同一函数中生成输入

问:那么编译器在
-o3
下做什么

答:它在构建时进行计算,并将结果存储在某种LUT中。(
.LC0

您应该初始化外部函数中的输入,最好是在不同的文件中,以避免编译器进行这种“构建时数学”欺骗

0=0.0f=0.0f*2.0f*0.0f
1073741824=2.0f=1.0f*2.0f*1.0f
1090519040=8.0f=2.0f*2.0f*2.0f

1099956224=18.0f=3.0f*2.0f*3.0f

这里看起来是矢量化的:从我到目前为止读到的内容来看,编译器首先评估矢量化的成本,然后如果开销没有带来任何好处,可能会决定生成标量代码。可能是这个工具没有评估这种情况。Godbolt使用的是GCC。我发布的链接是针对GCC 7.4和-O3生成的内容。你能把你完成的装配贴出来吗?完成了。请注意,寄存器q1有128位加载/存储。这里看起来是矢量化的:根据我目前所读的内容,编译器首先评估矢量化的成本,然后如果开销没有带来任何好处,则可能决定生成标量代码。可能是这个工具没有评估这种情况。Godbolt使用的是GCC。我发布的链接是针对GCC 7.4和-O3生成的内容。你能把你完成的装配贴出来吗?完成了。请注意,寄存器q1有128位加载/存储。谢谢您的建议。我一有电脑在我面前就去试试。马上。当我将输入数组的填充移动到一个函数(在同一个文件中)时,g++就对代码进行了矢量化。谢谢大家。谢谢你的建议。我一有电脑在我面前就去试试。马上。当我将输入数组的填充移动到一个函数(在同一个文件中)时,g++就对代码进行了矢量化。谢谢大家。
#include <iostream>
#include <cstdint>

int main(void)
    {
    const uint32_t  LEN = 16;
    float           input_1[LEN] __attribute__((__aligned__(16))),
                    input_2[LEN] __attribute__((__aligned__(16))),
                    output [LEN] __attribute__((__aligned__(16)));

    for(uint32_t i = 0; i < LEN; i++)
        {
        input_1[i] = i;
        input_2[i] = i * 2;
        }

    for(uint32_t i = 0; i < LEN; i++)
        output[i] = input_1[i] * input_2[i];

    std::cout << output[0] << std::endl;

    return 0;
    }
    .arch armv8-a
    .file   "neon_test.cpp"
    .text
    .section    .text.startup,"ax",@progbits
    .align  2
    .p2align 3,,7
    .global main
    .type   main, %function
main:
.LFB1563:
    .cfi_startproc
    stp x29, x30, [sp, -112]!
    .cfi_def_cfa_offset 112
    .cfi_offset 29, -112
    .cfi_offset 30, -104
    adrp    x1, .LC0
    adrp    x0, :got:_ZSt4cout
    movi    d0, #0
    add x29, sp, 0
    .cfi_def_cfa_register 29
    str x19, [sp, 16]
    .cfi_offset 19, -96
    adrp    x19, :got:__stack_chk_guard
    ldr q1, [x1, #:lo12:.LC0]
    ldr x19, [x19, #:got_lo12:__stack_chk_guard]
    ldr x0, [x0, #:got_lo12:_ZSt4cout]
    ldr x1, [x19]
    str x1, [x29, 104]
    mov x1,0
    str q1, [x29, 32]
    bl  _ZNSo9_M_insertIdEERSoT_
    bl  _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    ldr x0, [x29, 104]
    ldr x1, [x19]
    eor x1, x0, x1
    cbnz    x1, .L5
    ldr x19, [sp, 16]
    mov w0, 0
    ldp x29, x30, [sp], 112
    .cfi_remember_state
    .cfi_restore 30
    .cfi_restore 29
    .cfi_restore 19
    .cfi_def_cfa 31, 0
    ret
.L5:
    .cfi_restore_state
    bl  __stack_chk_fail
    .cfi_endproc
.LFE1563:
    .size   main, .-main
    .section    .rodata.cst16,"aM",@progbits,16
    .align  4
.LC0:
    .word   0
    .word   1073741824
    .word   1090519040
    .word   1099956224
    .section    .text.startup
    .align  2
    .p2align 3,,7
    .type   _GLOBAL__sub_I_main, %function
_GLOBAL__sub_I_main:
.LFB2050:
    .cfi_startproc
    stp x29, x30, [sp, -32]!
    .cfi_def_cfa_offset 32
    .cfi_offset 29, -32
    .cfi_offset 30, -24
    add x29, sp, 0
    .cfi_def_cfa_register 29
    str x19, [sp, 16]
    .cfi_offset 19, -16
    adrp    x19, .LANCHOR0
    add x19, x19, :lo12:.LANCHOR0
    mov x0, x19
    bl  _ZNSt8ios_base4InitC1Ev
    adrp    x0, :got:_ZNSt8ios_base4InitD1Ev
    mov x1, x19
    ldr x19, [sp, 16]
    adrp    x2, __dso_handle
    ldr x0, [x0, #:got_lo12:_ZNSt8ios_base4InitD1Ev]
    add x2, x2, :lo12:__dso_handle
    ldp x29, x30, [sp], 32
    .cfi_restore 30
    .cfi_restore 29
    .cfi_restore 19
    .cfi_def_cfa 31, 0
    b   __cxa_atexit
    .cfi_endproc
.LFE2050:
    .size   _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
    .section    .init_array,"aw"
    .align  3
    .xword  _GLOBAL__sub_I_main
    .bss
    .align  3
    .set    .LANCHOR0,. + 0
    .type   _ZStL8__ioinit, %object
    .size   _ZStL8__ioinit, 1
_ZStL8__ioinit:
    .zero   1
    .hidden __dso_handle
    .ident  "GCC: (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) 7.4.0"
    .section    .note.GNU-stack,"",@progbits