diff --git a/.appveyor.yml b/.appveyor.yml index 9e3436010..66d4e80ed 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -14,7 +14,7 @@ environment: APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2019' configuration: Release CMAKE_CUSTOM_OPTIONS: "-DCMAKE_BUILD_TYPE=Release \ - -DFORCE_SSE41=ON \ + -DARCH_OPT=SSE4_2 \ -DDEBUG_OUTPUT=ON \ -DENABLE_MIRISDR=OFF \ -DBUILD_SERVER=OFF \ @@ -25,7 +25,7 @@ environment: CC: "gcc-9" CXX: "g++-9" CMAKE_CUSTOM_OPTIONS: "-DCMAKE_BUILD_TYPE=Release \ - -DFORCE_SSE41=ON \ + -DARCH_OPT=nehalem \ -DDEBUG_OUTPUT=ON \ -DENABLE_EXTERNAL_LIBRARIES=ON \ -DBUILD_SERVER=OFF" @@ -86,7 +86,7 @@ for: libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \ libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev \ python3-mako python3-cheetah python3-numpy \ - autoconf automake libtool ninja-build + autoconf automake libtool ninja-build libclang1-9 - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES=ON" ]]; then bash cmake/ci/build_cm256cc.sh; fi - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES=ON" ]]; then bash cmake/ci/build_mbelib.sh; fi - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES=ON" ]]; then bash cmake/ci/build_serialdv.sh; fi diff --git a/.travis.yml b/.travis.yml index 5748a018b..2b1625359 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,4 +85,4 @@ script: - bash -c pwd - bash cmake/ci/build_sdrangel.sh env: - - CMAKE_CUSTOM_OPTIONS="-DFORCE_SSE41=ON -DBUNDLE=ON -DENABLE_PACK_MIRSDRAPI=ON" + - CMAKE_CUSTOM_OPTIONS="-DARCH_OPT=nehalem -DBUNDLE=ON -DENABLE_PACK_MIRSDRAPI=ON" diff --git a/CMakeLists.txt b/CMakeLists.txt index e48c369c4..9ca27aa96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,8 @@ option(BUILD_SERVER "Build Server" ON) option(BUILD_GUI "Build GUI" ON) option(HIDE_CONSOLE "Hide console when running GUI on Windows" ON) option(BUNDLE "Enable distribution bundle" OFF) -option(FORCE_SSSE3 "Compile with SSSE3 instruction only" OFF) -option(FORCE_SSE41 "Compile with SSE4.1 instruction only" OFF) +set(ARCH_OPT "native" CACHE STRING "Specify instruction set to use. Will be passed directly as `-march` or `/arch:` argument on supported compilers. \ + 'native' option will figure out host machine compatibilities and set flags accordingly (even with MSVC).") option(ENABLE_AIRSPY "Enable AirSpy support" ON) option(ENABLE_AIRSPYHF "Enable AirSpyHF support" ON) option(ENABLE_BLADERF "Enable bladeRF support" ON) @@ -208,11 +208,6 @@ elseif (WIN32) message(FATAL_ERROR "You must use Microsoft Visual Studio 2015, 2017 or 2019 as compiler") endif() - # compile with full multicore - if(MSVC) - add_compile_options(/MP) - endif() - # in alternative we can use ExternalProject set(EXTERNAL_LIBRARY_FOLDER "${CMAKE_SOURCE_DIR}/external/windows") set(FFTW3F_FOUND ON CACHE INTERNAL "") @@ -281,45 +276,11 @@ set(CMAKE_INSTALL_NAME_DIR # enable 24 bit receiving path if (RX_SAMPLE_24BIT) message(STATUS "Compiling for 24 bit Rx DSP chain") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSDR_RX_SAMPLE_24BIT") + add_compile_definitions(SDR_RX_SAMPLE_24BIT) else() message(STATUS "Compiling for 16 bit Rx DSP chain") endif() -if (SANITIZE_ADDRESS) - message(STATUS "Activate address sanitization") - if(MSVC) - set(ASAN_LIB_ARCH ${MSVC_CXX_ARCHITECTURE_ID}) - string(TOLOWER ${ASAN_LIB_ARCH} ASAN_LIB_ARCH) - if(ASAN_LIB_ARCH STREQUAL "x86") - set(ASAN_LIB_ARCH "i386") - elseif(ASAN_LIB_ARCH STREQUAL "x64") - set(ASAN_LIB_ARCH "x86_64") - endif() - add_compile_options(/fsanitize=address) - link_libraries(clang_rt.asan_dynamic-${ASAN_LIB_ARCH} clang_rt.asan_dynamic_runtime_thunk-${ASAN_LIB_ARCH}) - add_link_options(/wholearchive:clang_rt.asan_dynamic_runtime_thunk-${ASAN_LIB_ARCH}.lib) - else() - add_compile_options(-fsanitize=address -fno-omit-frame-pointer -g) - add_link_options(-fsanitize=address) - endif() -endif() - -# set compiler -include(FindCompiler) - -if (C_CLANG OR C_GCC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wvla -Woverloaded-virtual -ffast-math -ftree-vectorize ${EXTRA_FLAGS}") -elseif (C_MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -MP ${EXTRA_FLAGS}") -endif() - -if (C_CLANG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ferror-limit=1") -elseif (C_GCC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=1") -endif() - # find cpu flags (and set compiler) include(FindCPUflags) @@ -460,13 +421,7 @@ add_subdirectory(logging) add_subdirectory(qrtplib) add_subdirectory(swagger) add_subdirectory(devices) - -# strange symbol dependency -# mainbench.obj : error LNK2001: unresolved external -# symbol "public: static float const decimation_scale<12>::scaleIn" (?scaleIn@?$decimation_scale@$0M@@@2MB) -if(NOT WIN32) - add_subdirectory(sdrbench) -endif() +add_subdirectory(sdrbench) if (BUILD_GUI) add_subdirectory(sdrgui) @@ -533,21 +488,19 @@ else() endif() ############ build sdrangel benchmark ################ -if(NOT WIN32) - set(sdrangelbench_SOURCES - appbench/main.cpp - ) +set(sdrangelbench_SOURCES + appbench/main.cpp +) - add_executable(sdrangelbench - ${sdrangelbench_SOURCES} - ) +add_executable(sdrangelbench + ${sdrangelbench_SOURCES} +) - target_link_libraries(sdrangelbench - Qt5::Multimedia - sdrbench - logging - ) -endif() +target_link_libraries(sdrangelbench + Qt5::Multimedia + sdrbench + logging +) ############ build sdrangel gui ################ if (BUILD_GUI) set(sdrangel_SOURCES @@ -593,9 +546,7 @@ if (BUILD_SERVER) endif() ############ install ################## -if(NOT WIN32) - install(TARGETS sdrangelbench DESTINATION ${INSTALL_BIN_DIR}) -endif() +install(TARGETS sdrangelbench DESTINATION ${INSTALL_BIN_DIR}) if (BUILD_GUI) install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION ${INSTALL_BIN_DIR}) endif() diff --git a/appbench/main.cpp b/appbench/main.cpp index 0c91a875c..be8005a0d 100644 --- a/appbench/main.cpp +++ b/appbench/main.cpp @@ -21,20 +21,22 @@ #include #include -#include -#include #include #include "loggerwithfile.h" #include "mainbench.h" #include "dsp/dsptypes.h" +#ifndef _WIN32 + +#include +#include + void handler(int sig) { fprintf(stderr, "quit the application by signal(%d).\n", sig); QCoreApplication::quit(); } -#ifndef _WIN32 void catchUnixSignals(const std::vector& quitSignals) { sigset_t blocking_mask; sigemptyset(&blocking_mask); diff --git a/cmake/Modules/FindCPUflags.cmake b/cmake/Modules/FindCPUflags.cmake index 0d2dd2971..82ca3c2ef 100644 --- a/cmake/Modules/FindCPUflags.cmake +++ b/cmake/Modules/FindCPUflags.cmake @@ -1,266 +1,241 @@ -# Clang or AppleClang (see CMP0025) -if(NOT DEFINED C_CLANG AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") +include_guard(GLOBAL) + +include(CheckCXXCompilerFlag) +include(CheckSymbolExists) +include(CMakePushCheckState) + +set(TEST_DIR ${PROJECT_SOURCE_DIR}/cmake/test) + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(C_CLANG 1) -elseif(NOT DEFINED C_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") +elseif(MAKE_CXX_COMPILER_ID MATCHES "GNU") set(C_GCC 1) -elseif(NOT DEFINED C_MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "MSVC") +elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(C_MSVC 1) endif() # Detect current compilation architecture and create standard definitions -include(CheckSymbolExists) -function(detect_architecture symbol arch) +macro(detect_architecture symbol arch) if (NOT DEFINED ARCHITECTURE) - set(CMAKE_REQUIRED_QUIET 1) check_symbol_exists("${symbol}" "" ARCHITECTURE_${arch}) - unset(CMAKE_REQUIRED_QUIET) - # The output variable needs to be unique across invocations otherwise - # CMake's crazy scope rules will keep it defined if (ARCHITECTURE_${arch}) - set(ARCHITECTURE "${arch}" PARENT_SCOPE) - set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) - add_definitions(-DARCHITECTURE_${arch}=1) + set(ARCHITECTURE ${arch}) + set(ARCHITECTURE_${arch} TRUE) + add_compile_definitions(ARCHITECTURE_${arch}) endif() endif() +endmacro() + +macro(force_ext_available extension) + message(STATUS "Looking for __${extension}__ - forced found") + set(HAS_${extension} 1 CACHE INTERNAL "") +endmacro() + +function(detect_extensions extension) + unset(HAS_${extension}) + if (ARGC EQUAL 2 AND (${ARGV1})) # force available + force_ext_available(${extension}) + endif() + check_symbol_exists("__${extension}__" "" HAS_${extension}) + if (HAS_${extension}) + add_compile_definitions(USE_${extension}) + endif() endfunction() -if (NOT ENABLE_GENERIC) - if (C_MSVC) - detect_architecture("_M_AMD64" x86_64) - detect_architecture("_M_IX86" x86) - detect_architecture("_M_ARM" ARM) - detect_architecture("_M_ARM64" ARM64) - else() - detect_architecture("__x86_64__" x86_64) - detect_architecture("__i386__" x86) - detect_architecture("__arm__" ARM) - detect_architecture("__aarch64__" ARM64) - endif() +function(detect_msvc_native_opt) + try_run(RUN_AVX512 COMPILE_AVX512 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx512.cxx" COMPILE_DEFINITIONS /arch:AVX512) + if (COMPILE_AVX512 AND RUN_AVX512 EQUAL 0) + set(ARCH_OPT "AVX512" PARENT_SCOPE) + return() + endif() + try_run(RUN_AVX2 COMPILE_AVX2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx2.cxx" COMPILE_DEFINITIONS /arch:AVX2) + if (COMPILE_AVX2 AND RUN_AVX2 EQUAL 0) + set(ARCH_OPT "AVX2" PARENT_SCOPE) + return() + endif() + try_run(RUN_AVX COMPILE_AVX "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx.cxx" COMPILE_DEFINITIONS /arch:AVX) + if (COMPILE_AVX AND RUN_AVX EQUAL 0) + set(ARCH_OPT "AVX" PARENT_SCOPE) + return() + endif() + + # Supporting 32-bit x86, what year is it? + set(COMPILE_DEF "") + set(ARCH_OPT "" PARENT_SCOPE) + if (ARCHITECTURE_x86) + set(COMPILE_DEF "/arch:SSE2") + set(ARCH_OPT "SSE2" PARENT_SCOPE) + endif() + + try_run(RUN_SSE42 COMPILE_SSE42 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse42.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE42 AND RUN_SSE42 EQUAL 0) + force_ext_available(SSE4_2) + return() + endif() + try_run(RUN_SSE41 COMPILE_SSE41 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse41.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE41 AND RUN_SSE41 EQUAL 0) + force_ext_available(SSE4_1) + return() + endif() + try_run(RUN_SSSE3 COMPILE_SSSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_ssse3.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSSE3 AND RUN_SSSE3 EQUAL 0) + force_ext_available(SSSE3) + return() + endif() + try_run(RUN_SSE3 COMPILE_SSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse3.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE3 AND RUN_SSE3 EQUAL 0) + force_ext_available(SSE3) + return() + endif() + try_run(RUN_SSE2 COMPILE_SSE2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse2.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE2 AND RUN_SSE2 EQUAL 0) + force_ext_available(SSE2) + return() + endif() + + if (ARCHITECTURE_x86) + # At this point we might as well... + set(ARCH_OPT "IA32" PARENT_SCOPE) + return() + endif() +endfunction() + +if (C_MSVC) + detect_architecture("_M_AMD64" x86_64) + detect_architecture("_M_IX86" x86) + detect_architecture("_M_ARM" ARM) + detect_architecture("_M_ARM64" ARM64) +else() + detect_architecture("__x86_64__" x86_64) + detect_architecture("__i386__" x86) + detect_architecture("__arm__" ARM) + detect_architecture("__aarch64__" ARM64) endif() if (NOT DEFINED ARCHITECTURE) - set(ARCHITECTURE "GENERIC") - set(ARCHITECTURE_GENERIC 1) - add_definitions(-DARCHITECTURE_GENERIC=1) + message(FATAL_ERROR "Not supported. Please add needed architecture detection.") endif() -message(STATUS "Target architecture: ${ARCHITECTURE}") -set(TEST_DIR ${PROJECT_SOURCE_DIR}/cmake/test) +# Note: On x86 MSVC's /arch:SSE2 enables all SSE intrinsics support and is default option. +# On x86_64 MSVC's SSE is supported and enabled, so only AVX selection is needed. -# flag that set the minimum cpu flag requirements -# used to create re-distribuitable binary -if (${ARCHITECTURE} MATCHES "x86_64|x86" AND (FORCE_SSSE3 OR FORCE_SSE41)) - if (FORCE_SSSE3) - set(HAS_SSSE3 ON CACHE BOOL "SSSE3 SIMD enabled") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3" ) - message(STATUS "Use SSSE3 SIMD instructions") - add_definitions(-DUSE_SSSE3) - elseif(C_MSVC) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - message(STATUS "Use MSVC SSSE3 SIMD instructions") - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_SSSE3) - endif() - elseif (FORCE_SSE41) - set(HAS_SSSE3 ON CACHE BOOL "SSSE3 SIMD enabled") - set(HAS_SSE4_1 ON CACHE BOOL "Architecture has SSE 4.1 SIMD enabled") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -msse4.1" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -msse4.1" ) - message(STATUS "Use SSE 4.1 SIMD instructions") - add_definitions(-DUSE_SSSE3) - add_definitions(-DUSE_SSE4_1) - elseif(C_MSVC) - # seems that from MSVC 2015 comiler doesn't support those flags - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - message(STATUS "Use SSE 4.1 SIMD instructions") - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_SSSE3) - add_definitions(-DUSE_SSE4_1) - endif() +if (FORCE_SSSE3) + message(WARNING "FORCE_SSSE3 flag is deprecated, please use ARCH_OPT option.") + set(ARCH_OPT "") + if (C_MSVC) + if (ARCHITECTURE_x86) + set(ARCH_OPT "SSE2") endif() -else () -if (${ARCHITECTURE} MATCHES "x86_64|x86") - if(C_MSVC) - try_run(RUN_SSE2 COMPILE_SSE2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse2.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_SSE2 COMPILE_SSE2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse2.cxx" COMPILE_DEFINITIONS -msse2 -O0) - endif() - if(COMPILE_SSE2 AND RUN_SSE2 EQUAL 0) - set(HAS_SSE2 ON CACHE BOOL "Architecture has SSSE2 SIMD enabled") - message(STATUS "Use SSE2 SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2" ) - add_definitions(-DUSE_SSE2) - elseif(C_MSVC) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_SSE2) - endif() - else() - set(HAS_SSE2 OFF CACHE BOOL "Architecture does not have SSSE2 SIMD enabled") - endif() - if(C_MSVC) - try_run(RUN_SSSE3 COMPILE_SSSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_ssse3.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_SSSE3 COMPILE_SSSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_ssse3.cxx" COMPILE_DEFINITIONS -mssse3 -O0) - endif() - if(COMPILE_SSSE3 AND RUN_SSSE3 EQUAL 0) - set(HAS_SSSE3 ON CACHE BOOL "Architecture has SSSE3 SIMD enabled") - message(STATUS "Use SSSE3 SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3" ) - add_definitions(-DUSE_SSSE3) - elseif(C_MSVC) - # seems not present on MSVC 2017 - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_SSSE3) - endif() - else() - set(HAS_SSSE3 OFF CACHE BOOL "Architecture does not have SSSE3 SIMD enabled") - endif() - if(C_MSVC) - try_run(RUN_SSE4_1 COMPILE_SSE4_1 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse41.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_SSE4_1 COMPILE_SSE4_1 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse41.cxx" COMPILE_DEFINITIONS -msse4.1 -O0) - endif() - if(COMPILE_SSE4_1 AND RUN_SSE4_1 EQUAL 0) - set(HAS_SSE4_1 ON CACHE BOOL "Architecture has SSE 4.1 SIMD enabled") - message(STATUS "Use SSE 4.1 SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -msse4.1" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -msse4.1" ) - add_definitions(-DUSE_SSE4_1) - elseif(C_MSVC) - # seems not present on MSVC 2017 - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_SSE4_1) - endif() - else() - set(HAS_SSE4_1 OFF CACHE BOOL "Architecture does not have SSE 4.1 SIMD enabled") - endif() - if(C_MSVC) - try_run(RUN_SSE4_2 COMPILE_SSE4_2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse42.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_SSE4_2 COMPILE_SSE4_2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse42.cxx" COMPILE_DEFINITIONS -msse4.2 -O0) - endif() - if(COMPILE_SSE4_2 AND RUN_SSE4_2 EQUAL 0) - set(HAS_SSE4_2 ON CACHE BOOL "Architecture has SSE 4.2 SIMD enabled") - message(STATUS "Use SSE 4.2 SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -msse4.2" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -msse4.2" ) - add_definitions(-DUSE_SSE4_2) - elseif(C_MSVC) - # seems not present on MSVC 2017 - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_SSE4_2) - endif() - else() - set(HAS_SSE4_2 OFF CACHE BOOL "Architecture does not have SSE 4.2 SIMD enabled") - endif() - if(C_MSVC) - try_run(RUN_AVX COMPILE_AVX "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_AVX COMPILE_AVX "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx.cxx" COMPILE_DEFINITIONS -mavx -O0) - endif() - if(COMPILE_AVX AND RUN_AVX EQUAL 0) - set(HAS_AVX ON CACHE BOOL "Architecture has AVX SIMD enabled") - message(STATUS "Use AVX SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mavx" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mavx" ) - add_definitions(-DUSE_AVX) - elseif(C_MSVC) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /arch:AVX" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox /arch:AVX" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_AVX) - endif() - else() - set(HAS_AVX OFF CACHE BOOL "Architecture does not have AVX SIMD enabled") - endif() - if(C_MSVC) - try_run(RUN_AVX2 COMPILE_AVX2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx2.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_AVX2 COMPILE_AVX2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx2.cxx" COMPILE_DEFINITIONS -mavx2 -O0) - endif() - if(COMPILE_AVX2 AND RUN_AVX2 EQUAL 0) - set(HAS_AVX2 ON CACHE BOOL "Architecture has AVX2 SIMD enabled") - message(STATUS "Use AVX2 SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mavx2" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mavx2" ) - add_definitions(-DUSE_AVX2) - elseif(C_MSVC) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /arch:AVX2" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox /arch:AVX2" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_AVX2) - endif() - else() - set(HAS_AVX2 OFF CACHE BOOL "Architecture does not have AVX2 SIMD enabled") - endif() - if(C_MSVC) - try_run(RUN_AVX512 COMPILE_AVX512 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx512.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_AVX512 COMPILE_AVX512 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx512.cxx" COMPILE_DEFINITIONS -mavx512f -O0) - endif() - if(COMPILE_AVX512 AND RUN_AVX512 EQUAL 0) - set(HAS_AVX512 ON CACHE BOOL "Architecture has AVX512 SIMD enabled") - message(STATUS "Use AVX512 SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mavx512f" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mavx512f" ) - add_definitions(-DUSE_AVX512) - elseif(C_MSVC) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /arch:AVX512" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /GL /Ot /Ox /arch:AVX512" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG" ) - add_definitions (/D "_CRT_SECURE_NO_WARNINGS") - add_definitions(-DUSE_AVX512) - endif() - else() - set(HAS_AVX512 OFF CACHE BOOL "Architecture does not have AVX512 SIMD enabled") - endif() -elseif(ARCHITECTURE_ARM) - if(C_MSVC) - try_run(RUN_NEON COMPILE_NEON "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_arm_neon.cxx" COMPILE_DEFINITIONS /O0) - else() - try_run(RUN_NEON COMPILE_NEON "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_arm_neon.cxx" COMPILE_DEFINITIONS -mfpu=neon -O0) - endif() - if(COMPILE_NEON AND RUN_NEON EQUAL 0) - set(HAS_NEON ON CACHE BOOL "Architecture has NEON SIMD enabled") - message(STATUS "Use NEON SIMD instructions") - if(C_GCC OR C_CLANG) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mfpu=neon" ) - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mfpu=neon" ) - add_definitions(-DUSE_NEON) - endif() - else() - set(HAS_NEON OFF CACHE BOOL "Architecture does not have NEON SIMD enabled") - endif() -elseif(ARCHITECTURE_ARM64) - # Advanced SIMD (aka NEON) is mandatory for AArch64 - set(HAS_NEON ON CACHE BOOL "Architecture has NEON SIMD enabled") - message(STATUS "Use NEON SIMD instructions") - add_definitions(-DUSE_NEON) + force_ext_available(SSSE3) + else() + set(FORCE_OPT "-mssse3") + endif() endif() + +if (FORCE_SSE41) + message(WARNING "FORCE_SSE41 flag is deprecated, please use ARCH_OPT option.") + set(ARCH_OPT "") + if (C_MSVC) + if (ARCHITECTURE_x86) + set(ARCH_OPT "SSE2") + else() + force_ext_available(SSE4_1) + endif() + else() + set(FORCE_OPT "-msse4.1") + endif() +endif() + +if (C_MSVC) + # Glue to make ARCH_OPT more flexible for MSVC + if (ARCH_OPT STREQUAL "native") + detect_msvc_native_opt() + elseif(ARCH_OPT STREQUAL "SSE4_2") + force_ext_available(SSE4_2) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSE4_1") + force_ext_available(SSE4_1) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSSE3") + force_ext_available(SSSE3) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSE3") + force_ext_available(SSE3) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSE2") + force_ext_available(SSE2) + set(ARCH_OPT "") + endif() +endif() + +message(STATUS "Target architecture: ${ARCHITECTURE}-${ARCH_OPT}") + +cmake_push_check_state(RESET) +if (ARCH_OPT) + if(C_MSVC) + set(CMAKE_REQUIRED_FLAGS "/arch:${ARCH_OPT}") + add_compile_options(${CMAKE_REQUIRED_FLAGS}) + else() + set(CMAKE_REQUIRED_FLAGS "-march=${ARCH_OPT}") + add_compile_options(-march=${ARCH_OPT}) + endif() +elseif(FORCE_SSSE3 OR FORCE_SSE41) + if (NOT C_MSVC) + set(CMAKE_REQUIRED_FLAGS ${FORCE_OPT}) + add_compile_options(${FORCE_OPT}) + endif() +endif() + +check_cxx_compiler_flag("${CMAKE_REQUIRED_FLAGS}" FLAG_SUPPORTED) +if (NOT FLAG_SUPPORTED) + message(FATAL_ERROR "Flag '${CMAKE_REQUIRED_FLAGS}' rejected by compiler. Please adjust ARCH_OPT option.") +endif() + +if (ARCHITECTURE_ARM) + if (C_MSVC) + force_ext_available(ARM_NEON) + else() + list(APPEND CMAKE_REQUIRED_FLAGS -mfpu=neon) + endif() +endif() + +# This is quite basic detection, can be extended if needed +detect_extensions(ARM_NEON) +detect_extensions(AVX512F) +detect_extensions(AVX2 HAS_AVX512F) +detect_extensions(AVX HAS_AVX2) +detect_extensions(SSE4_2 HAS_AVX) +detect_extensions(SSE4_1 HAS_SSE4_2) +detect_extensions(SSSE3 HAS_SSE4_1) +detect_extensions(SSE3 HAS_SSSE3) +detect_extensions(SSE2 HAS_SSE3) + +cmake_pop_check_state() + +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) +if (C_CLANG OR C_GCC) + add_compile_options(-Wall -Wextra -Wvla -Woverloaded-virtual -ffast-math -ftree-vectorize) +elseif (C_MSVC) + add_compile_options(/MP) +endif() + +if (SANITIZE_ADDRESS) + message(STATUS "Activate address sanitization") + if(MSVC) + set(ASAN_LIB_ARCH ${MSVC_CXX_ARCHITECTURE_ID}) + string(TOLOWER ${ASAN_LIB_ARCH} ASAN_LIB_ARCH) + if(ASAN_LIB_ARCH STREQUAL "x86") + set(ASAN_LIB_ARCH "i386") + elseif(ASAN_LIB_ARCH STREQUAL "x64") + set(ASAN_LIB_ARCH "x86_64") + endif() + add_compile_options(/fsanitize=address) + link_libraries(clang_rt.asan_dynamic-${ASAN_LIB_ARCH} clang_rt.asan_dynamic_runtime_thunk-${ASAN_LIB_ARCH}) + add_link_options(/wholearchive:clang_rt.asan_dynamic_runtime_thunk-${ASAN_LIB_ARCH}.lib) + else() + add_compile_options(-fsanitize=address -fno-omit-frame-pointer -g) + add_link_options(-fsanitize=address) + endif() endif() # clear binary test folder diff --git a/cmake/Modules/FindCompiler.cmake b/cmake/Modules/FindCompiler.cmake deleted file mode 100644 index 1bd630323..000000000 --- a/cmake/Modules/FindCompiler.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# Clang or AppleClang (see CMP0025) -if(NOT DEFINED C_CLANG AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(C_CLANG 1) -elseif(NOT DEFINED C_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(C_GCC 1) -elseif(NOT DEFINED C_MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set(C_MSVC 1) -endif() diff --git a/debian/rules b/debian/rules index 3d4bf9ddb..1a04209de 100755 --- a/debian/rules +++ b/debian/rules @@ -2,9 +2,8 @@ %: dh $@ --parallel --buildsystem=cmake+ninja -# FORCE_SSE41 will be not accepted upstream override_dh_auto_configure: - dh_auto_configure -- -DFORCE_SSE41=ON -DENABLE_EXTERNAL_LIBRARIES=ON -DDEBUG_OUTPUT=ON -DBUILD_SERVER=OFF + dh_auto_configure -- -DARCH_OPT=nehalem -DENABLE_EXTERNAL_LIBRARIES=ON -DDEBUG_OUTPUT=ON -DBUILD_SERVER=OFF override_dh_auto_test: echo "Skipping test step" diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 045fed630..48f9c4e14 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -68,6 +68,7 @@ elseif (LINUX) ) endif () +list(APPEND COMMON_CMAKE_ARGS -DCMAKE_POLICY_DEFAULT_CMP0069:STRING=NEW) if(CMAKE_MSVC_RUNTIME_LIBRARY) list(APPEND COMMON_CMAKE_ARGS -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW) list(APPEND COMMON_CMAKE_ARGS -DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}) @@ -77,6 +78,10 @@ if(CMAKE_BUILD_TYPE) list(APPEND COMMON_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) endif() +if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + list(APPEND COMMON_CMAKE_ARGS -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=${CMAKE_INTERPROCEDURAL_OPTIMIZATION}) +endif() + list(APPEND COMMON_CMAKE_ARGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}) list(APPEND COMMON_CMAKE_ARGS -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED}) list(APPEND COMMON_CMAKE_ARGS -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}) diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 9e3fb0353..93fe2a50a 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -99,7 +99,6 @@ set(sdrbase_SOURCES dsp/channelsamplesource.cpp dsp/cwkeyer.cpp dsp/cwkeyersettings.cpp - dsp/decimatorsif.cpp dsp/decimatorsff.cpp dsp/decimatorsfi.cpp dsp/decimatorc.cpp diff --git a/sdrbase/dsp/decimatorsif.cpp b/sdrbase/dsp/decimatorsif.cpp deleted file mode 100644 index 5a443642f..000000000 --- a/sdrbase/dsp/decimatorsif.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2018 Edouard Griffiths, F4EXB // -// // -// This program is free software; you can redistribute it and/or modify // -// it under the terms of the GNU General Public License as published by // -// the Free Software Foundation as version 3 of the License, or // -// (at your option) any later version. // -// // -// This program is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU General Public License V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include "decimatorsif.h" - -const float decimation_scale<8>::scaleIn = 1.0/128.0; -const float decimation_scale<12>::scaleIn = 1.0/2048.0; -const float decimation_scale<16>::scaleIn = 1.0/32768.0; - diff --git a/sdrbase/dsp/decimatorsif.h b/sdrbase/dsp/decimatorsif.h index 90a7975bf..24ab35d56 100644 --- a/sdrbase/dsp/decimatorsif.h +++ b/sdrbase/dsp/decimatorsif.h @@ -26,31 +26,9 @@ template struct decimation_scale { - static const float scaleIn; + static constexpr float scaleIn = 1.0f / (1 << (InputBits - 1)); }; -template -const float decimation_scale::scaleIn = 1.0; - -template<> -struct decimation_scale<8> -{ - static const float scaleIn; -}; - -template<> -struct decimation_scale<12> -{ - static const float scaleIn; -}; - -template<> -struct decimation_scale<16> -{ - static const float scaleIn; -}; - - template class DecimatorsIF { public: diff --git a/sdrbench/mainbench.h b/sdrbench/mainbench.h index c92f603f1..20510a39e 100644 --- a/sdrbench/mainbench.h +++ b/sdrbench/mainbench.h @@ -29,6 +29,7 @@ #include "dsp/decimatorsfi.h" #include "dsp/decimatorsff.h" #include "parserbench.h" +#include "export.h" namespace qtwebapp { class LoggerWithFile; @@ -38,8 +39,8 @@ class MainBench: public QObject { Q_OBJECT public: - explicit MainBench(qtwebapp::LoggerWithFile *logger, const ParserBench& parser, QObject *parent = 0); - ~MainBench(); + SDRBASE_API explicit MainBench(qtwebapp::LoggerWithFile *logger, const ParserBench& parser, QObject *parent = 0); + SDRBASE_API ~MainBench(); public slots: void run(); diff --git a/sdrbench/parserbench.h b/sdrbench/parserbench.h index 013578382..f9ae7000f 100644 --- a/sdrbench/parserbench.h +++ b/sdrbench/parserbench.h @@ -22,6 +22,8 @@ #include #include +#include "export.h" + class ParserBench { public: @@ -36,10 +38,10 @@ public: TestAMBE } TestType; - ParserBench(); - ~ParserBench(); + SDRBASE_API ParserBench(); + SDRBASE_API ~ParserBench(); - void parse(const QCoreApplication& app); + SDRBASE_API void parse(const QCoreApplication& app); const QString& getTestStr() const { return m_testStr; } TestType getTestType() const;