【问题标题】:inlining failed in call to always_inline ‘_mm_mullo_epi32’: target specific option mismatch调用 always_inline ‘_mm_mullo_epi32’ 时内联失败:目标特定选项不匹配
【发布时间】:2021-03-21 11:05:50
【问题描述】:

我正在尝试使用使用 SIMD 内在函数的 cmake 编译 C 程序。当我尝试编译它时,我得到了两个错误

/usr/lib/gcc/x86_64-linux-gnu/5/include/smmintrin.h:326:1:错误:调用 always_inline '_mm_mullo_epi32'时内联失败:目标特定选项错配 _mm_mullo_epi32 (__m128i __X, __m128i __Y)

/usr/lib/gcc/x86_64-linux-gnu/5/include/tmmintrin.h:136:1: 错误:调用 always_inline '_mm_shuffle_epi8' 时内联失败:目标特定选项错配 _mm_shuffle_epi8 (__m128i __X, __m128i __Y)

这个问题已经在这里StackOverflow通过设置解决了

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")

我尝试了相同的选项和许多其他选项。但是我的项目仍然无法编译。

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")  
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -sse4_1")  
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=nehalem")  
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1 -msse4.2")  
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")  
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ssse3")  

【问题讨论】:

    标签: c cmake x86 sse simd


    【解决方案1】:

    由于您正在编译 C 代码,而不是 C++,因此您需要:

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.1")
    

    您可以摆脱所有其他 -march XXX-msseXXX 设置。

    如果您混合使用 C 和 C++,那么您还可以添加:

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
    

    【讨论】:

    • 我还必须添加 -maes 或 ti 对我​​不起作用 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1 -maes")
    • 或者更好,如果为你自己的机器编译,使用-march=native。这将启用您的 CPU 所拥有的一切,并设置调整选项。
    【解决方案2】:

    寻找gcc指令开关的通用方法

    文件 intrin.sh:

    #!/bin/bash
    
    get_instruction ()
    {
        [ -z "$1" ] && exit
        func_name="$1 "
    
        header_file=`grep --include=\*intrin.h -Rl "$func_name" /usr/lib/gcc | head -n1`
        [ -z "$header_file" ] && exit
        >&2 echo "find in: $header_file"
    
        target_directive=`grep "#pragma GCC target(\|$func_name" $header_file | grep -B 1 "$func_name" | head -n1`
        echo $target_directive | grep -o '"[^,]*[,"]' | sed 's/"//g' | sed 's/,//g'
    }
    
    instruction=`get_instruction $1`
    if [ -z "$instruction" ]; then
        echo "Error: function not found: $1"
    else
        echo "add this option to gcc: -m$instruction"
    fi
    

    用法:

    ./intrin.sh _mm_shuffle_epi8      # output: -mssse3
    ./intrin.sh _mm_cvtepu8_epi32     # output: -msse4.1
    ./intrin.sh _mm_loadu_ps          # output: -msse
    ./intrin.sh _mm_clmulepi64_si128  # output: -mpclmul
    ./intrin.sh _mm256_loadu_si256    # output: -mavx
    ./intrin.sh _mm512_and_ps         # output: -mavx512dq
    

    【讨论】:

    • 请注意,使用-march=haswell 之类的东西通常是个好主意,而不仅仅是-mavx2 -mfma。或者至少在您的-m ISA 选项中添加-mtune=znver2 (Zen 2) 或其他内容。对于可能未对齐的 256 位向量,“通用”调整可能非常糟糕,尤其是当您的数据通常在运行时对齐但编译器不知道这一点时。见Why doesn't gcc resolve _mm256_loadu_pd as single vmovupd?。或者,如果您想为自己的机器制作二进制文件,-march=native
    • 感谢精彩的脚本。拯救了我的一天。
    • 很好的答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2016-12-05
    相关资源
    最近更新 更多