Visual Studio无法识别__AVX2__或__AVX__

Visual Studio not recognizing __AVX2__ or __AVX__

本文关键字:AVX2 AVX 识别 Studio Visual      更新时间:2023-10-16

我正在C++中实现一个简单的 SIMD 包装器。为了使其跨平台,我使用CMake通过Visual Studio设置项目。

我添加了/Arch:AVX2,但 Visual Studio 无法识别__AVX2__宏。

首先,我的CMake。

cmake_minimum_required(VERSION 3.12.2)
set(INCLUDEDIR "include/Maths")
set(SOURCEDIR "src")
set(HEADER_FILES
    ${INCLUDEDIR}/export.h 
    ${INCLUDEDIR}/SIMDWrapper/Config/SIMDConfig.h)
set(SOURCE_FILES 
    ${SOURCEDIR}/Application.cpp)

add_library(Maths SHARED ${SOURCE_FILES}  ${HEADER_FILES})
target_link_libraries(Maths PUBLIC Core)
target_include_directories(Maths PUBLIC "include")
target_compile_options(Maths PRIVATE $<$<BOOL:${MSVC}>:/arch:AVX2>)
target_compile_definitions(Maths PRIVATE MATHS_EXPORT)

还有我的头文件(来自Agner Fog的VectorClass instrset.h):

#pragma once
#if (defined(_M_AMD64) || defined(_M_X64) || defined(__amd64)) && ! 
    defined(__x86_64__)
#define __x86_64__ 1
#endif

#ifndef SIMD_INSTR_SET
#if defined (__AVX2__)
    #define SIMD_INSTR_SET 8
#elif defined ( __AVX__ )
    #define SIMD_INSTR_SET 7
#elif defined ( __SSE4_2__ )
    #define SIMD_INSTR_SET 6
#elif defined ( __SSE4_1__ )
    #define SIMD_INSTR_SET 5
#elif defined ( __SSSE3__ )
    #define SIMD_INSTR_SET 4
#elif defined ( __SSE3__ )
    #define SIMD_INSTR_SET 3
#elif defined ( __SSE2__ ) || defined ( __x86_64__ )
    #define SIMD_INSTR_SET 2 //this is where the color has changed
#elif defined ( __SSE__ )
    #define SIMD_INSTR_SET 1
#elif defined ( _M_IX86_FP )    
   #define SIMD_INSTR_SET _M_IX86_FP
#else
   #define SIMD_INSTR_SET 0
#endif // instruction set defines
#endif // SIMD_INSTR_SET

这就是我所做的。 __x86_64__定义,我的CPU是i5 Skylake,所以它应该支持AVX2。

我已经检查了是否从项目配置属性中启用了高级矢量扩展 2 选项,并且已启用。

我需要从CMake或Visual Studio更改/添加一些内容以使AVX2宏可识别吗?

三种方法可以在目标/arch:AVX2启用编译选项(如果编译器支持)。

通过使用生成器表达式

target_compile_options(Maths PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/arch:AVX2>)

或通过在if子句中设置 compile 选项

if(MSVC)
    target_compile_options(Maths PRIVATE /arch:AVX2)
endif()

或者使用 add_definition 调用将定义添加到在此命令之后在脚本中创建的所有目标

if(MSVC)
    add_definition(/arch:AVX2)
endif()

如果不是绝对必要,我会尽量避免使用生成器表达式,因为它们不会提高 CMake 脚本文件的可读性,有时很难正确。