调用always_inline'_mm_mullo_epi32'时内联失败:目标特定选项不匹配

New*_*101 8 c x86 sse simd cmake

我正在尝试使用使用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")
Run Code Online (Sandbox Code Playgroud)

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

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")  
Run Code Online (Sandbox Code Playgroud)

小智 10

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
Run Code Online (Sandbox Code Playgroud)

用法:

./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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,使用“-march=haswell”之类的东西通常是个好主意,而不仅仅是“-mavx2 -mfma”。或者至少将 `-mtune=znver2` (Zen 2) 或其他内容添加到您的 `-m` ISA 选项中。对于可能未对齐的 256 位向量,“通用”调整可能非常差,尤其是当您的数据通常在运行时对齐但编译器不知道这一点时。请参阅[为什么 gcc 不将 \_mm256\_loadu\_pd 解析为单个 vmovupd?](/sf/ask/3683870851/)。或者,如果您想为自己的机器制作二进制文件,请使用“-march=native”。 (2认同)

Pau*_*l R 8

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

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.1")
Run Code Online (Sandbox Code Playgroud)

你可以摆脱所有其他-march XXX和-msseXXX设置.

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

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
Run Code Online (Sandbox Code Playgroud)

  • 或者更好的是,如果为您自己的机器进行编译,请使用“-march=native”。这将启用您的 CPU 的所有功能,并设置调整选项。 (3认同)
  • 我还必须添加 -maes 或 ti 对我​​不起作用 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1 -maes") (2认同)