使用Agner Fog向量类在MSVC编译下性能骤降的问题求助
问题:MSVC编译下Agner Fog向量类性能比原生SSE/AVX慢10倍以上
我在测试原生SSE/AVX函数与Agner Fog's vector class(我的CPU支持SSE和AVX指令)的性能差异时,GNU编译器(版本12.2)下结果完全符合预期,但切换到MSVC(VS2019/Clion环境)编译后,所有向量类实现的性能比原生SSE/AVX函数慢10倍甚至更多。
我的CMake编译配置如下:
cmake_minimum_required(VERSION 3.21) project(testSIMD) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/external_modules/cmakeFind/") set(CMAKE_CXX_STANDARD 17) set(USE_VECTORIZE ON) if (NOT VECTOR_TYPE) set(VECTOR_TYPE full_vectorize) endif (NOT VECTOR_TYPE) if (VECTOR_TYPE STREQUAL "none") set(VECTOR_TYPE none) endif (VECTOR_TYPE STREQUAL "none") if (VECTOR_TYPE STREQUAL "default") set(VECTOR_TYPE default) endif (VECTOR_TYPE STREQUAL "default") # Set vectorization flags for a few compilers set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") find_package(VectorFOG REQUIRED) #Pushing vector flags onto compiler flags for try compiles set(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS}) set(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VECTOR_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${VECTOR_CXX_FLAGS}") try_compile(HAVE_FOG_VECTOR_CLASS "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/fogvectorclasstest.cpp") if(HAVE_FOG_VECTOR_CLASS) message(STATUS "Trying Fog Vector Class -- works") add_definitions(-DHAVE_FOG_VECTOR_CLASS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAX_VECTOR_SIZE=512") set (FILE_LIST ${FILE_LIST} kahan_fog_vector.cpp kahan_fog_vector8.cpp) else() message(STATUS "Trying Fog Vector Class -- fails") endif() # Set vectorization flags for GNU compiler if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC if (USE_VECTORIZE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -fstrict-aliasing -fopenmp-simd -march=native -mtune=native -ffast-math -ftree-vectorize -fopt-info-vec-optimized") else () set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -fstrict-aliasing -march=native -mtune=native -ffast-math -fno-tree-vectorize -fopt-info-vec-optimized") endif () if ("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER "7.4.0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mprefer-vector-width=512") endif ("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER "7.4.0") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # using Clang set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -fstrict-aliasing -fvectorize -march=native -mtune=native -ffast-math -Rpass-analysis=loop-vectorize") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O3") add_compile_options(/arch:AVX2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qvec-report:2") endif ()
可能的原因及修复方案
- 缺少快速数学优化选项:
MSVC默认的浮点精度策略会限制向量优化,需添加/fp:fast选项(对应GCC的-ffast-math),这是Agner Fog向量类发挥性能的关键。修改MSVC分支的配置:elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O3 /fp:fast") add_compile_options(/arch:AVX2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qvec-report:2") endif () - MAX_VECTOR_SIZE定义格式错误:
MSVC使用/D而非GCC的-D来定义宏,需要针对编译器区分宏定义方式:if(HAVE_FOG_VECTOR_CLASS) message(STATUS "Trying Fog Vector Class -- works") add_definitions(-DHAVE_FOG_VECTOR_CLASS) if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DMAX_VECTOR_SIZE=512") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAX_VECTOR_SIZE=512") endif() set (FILE_LIST ${FILE_LIST} kahan_fog_vector.cpp kahan_fog_vector8.cpp) else() message(STATUS "Trying Fog Vector Class -- fails") endif() - VectorFOG的编译标志未保留:
try_compile后恢复了原编译标志,导致VECTOR_CXX_FLAGS没有应用到最终编译中,需在MSVC分支中添加:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${VECTOR_CXX_FLAGS}") - 检查向量化报告:
查看/Qvec-report:2的输出,确认向量类相关代码是否被成功向量化。如果未被向量化,可在循环前添加#pragma loop(enable_vectorization)强制MSVC进行向量化。
内容的提问来源于stack exchange,提问作者hamster_watcher
相关产品推荐
相关产品推荐

