I'm implementing a simple SIMD wrapper in C++. To make it cross-platform, I use CMake to set-up the project with Visual Studio
I've added /Arch:AVX2, but Visual Studio does not recognize __AVX2__
Macro.
First, my 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)
And my Header File (from Agner Fog's 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
This is what I did.
__x86_64__
is defined, my CPU is i5 Skylake so it should support AVX2.
I've checked if Advanced Vector Extensions 2 option is enabled from Project Configuration Properties, and it is enabled.
Is there something I need to change/add from CMake or Visual Studio to make the AVX2 Macro recognizable?
There are three ways to enable the compile option /arch:AVX2
to your target (if it is supported by your compiler).
Either by using a generator expression
target_compile_options(Maths PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/arch:AVX2>)
or by setting the compile option in a if
clause
if(MSVC)
target_compile_options(Maths PRIVATE /arch:AVX2)
endif()
or by using an add_definitions
call to add the definitions to all targets that are created in the script after this command
if(MSVC)
add_definitions(/arch:AVX2)
endif()
I try to avoid using generator expressions if not absolutely necessary as they do not improve readability of the CMake script files and are sometimes hard to get right.