From d717de571900258dac325fd0c29e39d9b7f45ca0 Mon Sep 17 00:00:00 2001 From: ocpalo Date: Fri, 5 Aug 2022 23:13:06 +0300 Subject: [PATCH 1/2] nasm/simd support for libjpeg-turbo --- 3rdparty/libjpeg-turbo/CMakeLists.txt | 114 +++++++++++++++++- .../libjpeg-turbo/src/simd/CMakeLists.txt | 25 ++-- CMakeLists.txt | 10 ++ modules/imgcodecs/perf/perf_jpeg.cpp | 38 ++++++ 4 files changed, 174 insertions(+), 13 deletions(-) create mode 100644 modules/imgcodecs/perf/perf_jpeg.cpp diff --git a/3rdparty/libjpeg-turbo/CMakeLists.txt b/3rdparty/libjpeg-turbo/CMakeLists.txt index 4dd3095f94..e316e24822 100644 --- a/3rdparty/libjpeg-turbo/CMakeLists.txt +++ b/3rdparty/libjpeg-turbo/CMakeLists.txt @@ -15,8 +15,55 @@ endif() message(STATUS "libjpeg-turbo: VERSION = ${VERSION}, BUILD = ${BUILD}") +math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8") +string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR_LC) + +if(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86_64" OR + CMAKE_SYSTEM_PROCESSOR_LC MATCHES "amd64" OR + CMAKE_SYSTEM_PROCESSOR_LC MATCHES "i[0-9]86" OR + CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86" OR + CMAKE_SYSTEM_PROCESSOR_LC MATCHES "ia32") + if(BITS EQUAL 64 OR CMAKE_C_COMPILER_ABI MATCHES "ELF X32") + set(CPU_TYPE x86_64) + else() + set(CPU_TYPE i386) + endif() + if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ${CPU_TYPE}) + set(CMAKE_SYSTEM_PROCESSOR ${CPU_TYPE}) + endif() +elseif(CMAKE_SYSTEM_PROCESSOR_LC STREQUAL "aarch64" OR + CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^arm") + if(BITS EQUAL 64) + set(CPU_TYPE arm64) + else() + set(CPU_TYPE arm) + endif() +elseif(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^ppc" OR + CMAKE_SYSTEM_PROCESSOR_LC MATCHES "^powerpc") + set(CPU_TYPE powerpc) +else() + set(CPU_TYPE ${CMAKE_SYSTEM_PROCESSOR_LC}) +endif() +if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR + CMAKE_OSX_ARCHITECTURES MATCHES "arm64" OR + CMAKE_OSX_ARCHITECTURES MATCHES "i386") + set(CPU_TYPE ${CMAKE_OSX_ARCHITECTURES}) +endif() +if(CMAKE_OSX_ARCHITECTURES MATCHES "ppc") + set(CPU_TYPE powerpc) +endif() +if(MSVC_IDE AND CMAKE_GENERATOR_PLATFORM MATCHES "arm64") + set(CPU_TYPE arm64) +endif() + +message(STATUS "${BITS}-bit build (${CPU_TYPE})") + +OCV_OPTION(ENABLE_LIBJPEG_TURBO_SIMD "Include SIMD extensions for libjpeg-turbo, if available for this platform" (NOT CV_DISABLE_OPTIMIZATION) + VISIBLE_IF BUILD_JPEG) option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE) option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE) +set(WITH_SIMD 1) +set(IS_LIBJPEG_TURBO_SIMD_AVAILABLE 0 PARENT_SCOPE) include(CheckCSourceCompiles) include(CheckIncludeFiles) @@ -99,12 +146,73 @@ if(WITH_ARITH_DEC) set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c) endif() -# No SIMD -set(JPEG_SOURCES ${JPEG_SOURCES} jsimd_none.c) +if(MSVC) + option(WITH_CRT_DLL + "Link all ${CMAKE_PROJECT_NAME} libraries and executables with the C run-time DLL (msvcr*.dll) instead of the static C run-time library (libcmt*.lib.) The default is to use the C run-time DLL only with the libraries and executables that need it." + FALSE) + if(NOT WITH_CRT_DLL) + # Use the static C library for all build types + foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}") + endif() + endforeach() + endif() + add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) +endif() + +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + # Use the maximum optimization level for release builds + foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${var} MATCHES "-O2") + string(REGEX REPLACE "-O2" "-O3" ${var} "${${var}}") + endif() + endforeach() +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + if(CMAKE_C_COMPILER_ID MATCHES "SunPro") + # Use the maximum optimization level for release builds + foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${var} MATCHES "-xO3") + string(REGEX REPLACE "-xO3" "-xO5" ${var} "${${var}}") + endif() + if(${var} MATCHES "-xO2") + string(REGEX REPLACE "-xO2" "-xO5" ${var} "${${var}}") + endif() + endforeach() + endif() +endif() + +message(STATUS ${WITH_LIBJPEG_TURBO_SIMD}) +if(ENABLE_LIBJPEG_TURBO_SIMD) + add_subdirectory(src/simd) + if(NEON_INTRINSICS) + add_definitions(-DNEON_INTRINSICS) + endif() +else() + set(WITH_SIMD 0) +endif() + +if(WITH_SIMD) + message(STATUS "SIMD extensions: ${CPU_TYPE} (WITH_SIMD = ${WITH_SIMD})") + set(IS_LIBJPEG_TURBO_SIMD_AVAILABLE 1 PARENT_SCOPE) + if(MSVC_IDE OR XCODE) + set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1) + endif() +else() + add_library(simd OBJECT src/jsimd_none.c) + if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)) + set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1) + endif() +endif() ocv_list_add_prefix(JPEG_SOURCES src/) -add_library(${JPEG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${JPEG_SOURCES} ${SIMD_OBJS}) +set(JPEG_SOURCES ${JPEG_SOURCES} ${SIMD_OBJS}) + +add_library(${JPEG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${JPEG_SOURCES} $ ${SIMD_OBJS}) set_target_properties(${JPEG_LIBRARY} PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY} diff --git a/3rdparty/libjpeg-turbo/src/simd/CMakeLists.txt b/3rdparty/libjpeg-turbo/src/simd/CMakeLists.txt index 8521e42b44..db85d9f443 100644 --- a/3rdparty/libjpeg-turbo/src/simd/CMakeLists.txt +++ b/3rdparty/libjpeg-turbo/src/simd/CMakeLists.txt @@ -1,9 +1,13 @@ macro(simd_fail message) - if(REQUIRE_SIMD) - message(FATAL_ERROR "${message}.") - else() message(WARNING "${message}. Performance will suffer.") set(WITH_SIMD 0 PARENT_SCOPE) +endmacro() + +macro(boolean_number var) + if(${var}) + set(${var} 1 ${ARGN}) + else() + set(${var} 0 ${ARGN}) endif() endmacro() @@ -41,14 +45,14 @@ elseif(CPU_TYPE STREQUAL "i386") endif() endif() -if(NOT REQUIRE_SIMD) - include(CheckLanguage) - check_language(ASM_NASM) - if(NOT CMAKE_ASM_NASM_COMPILER) - simd_fail("SIMD extensions disabled: could not find NASM compiler") - return() - endif() + +include(CheckLanguage) +check_language(ASM_NASM) +if(NOT CMAKE_ASM_NASM_COMPILER) + simd_fail("SIMD extensions disabled: could not find NASM compiler") + return() endif() + enable_language(ASM_NASM) message(STATUS "CMAKE_ASM_NASM_COMPILER = ${CMAKE_ASM_NASM_COMPILER}") @@ -224,6 +228,7 @@ elseif(CPU_TYPE STREQUAL "arm64" OR CPU_TYPE STREQUAL "arm") # following test determines whether -mfloat-abi=softfp should be explicitly # added to the compile flags for the intrinsics implementation of the Neon SIMD # extensions. + if(BITS EQUAL 32) check_c_source_compiles(" #if defined(__ARM_NEON__) || (!defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__)) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43b6023242..129cf0aae2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1341,6 +1341,16 @@ if(WITH_JPEG OR HAVE_JPEG) status(" JPEG:" NO) elseif(BUILD_JPEG) status(" JPEG:" "build-${JPEG_LIBRARY} (ver ${JPEG_LIB_VERSION})") + if(ENABLE_LIBJPEG_TURBO_SIMD) + status(" SIMD Support Request:" "YES") + if(IS_LIBJPEG_TURBO_SIMD_AVAILABLE) + status(" SIMD Support:" "YES") + else() + status(" SIMD Support:" "NO") + endif() + else() + status(" SIMD Support Request:" "NO") + endif() else() status(" JPEG:" "${JPEG_LIBRARY} (ver ${JPEG_LIB_VERSION})") endif() diff --git a/modules/imgcodecs/perf/perf_jpeg.cpp b/modules/imgcodecs/perf/perf_jpeg.cpp new file mode 100644 index 0000000000..694e2e698e --- /dev/null +++ b/modules/imgcodecs/perf/perf_jpeg.cpp @@ -0,0 +1,38 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html +#include "perf_precomp.hpp" + +namespace opencv_test +{ +using namespace perf; + +PERF_TEST(JPEG, Decode) +{ + String filename = getDataPath("stitching/boat1.jpg"); + + FILE *f = fopen(filename.c_str(), "rb"); + fseek(f, 0, SEEK_END); + long len = ftell(f); + fseek(f, 0, SEEK_SET); + vector file_buf((size_t)len); + EXPECT_EQ(len, (long)fread(&file_buf[0], 1, (size_t)len, f)); + fclose(f); f = NULL; + + TEST_CYCLE() imdecode(file_buf, IMREAD_UNCHANGED); + + SANITY_CHECK_NOTHING(); +} + +PERF_TEST(JPEG, Encode) +{ + String filename = getDataPath("stitching/boat1.jpg"); + cv::Mat src = imread(filename); + + vector buf; + TEST_CYCLE() imencode(".jpg", src, buf); + + SANITY_CHECK_NOTHING(); +} + +} // namespace \ No newline at end of file From 04849f26b2c20465d475a29c86bb92351502c8f3 Mon Sep 17 00:00:00 2001 From: ocpalo Date: Tue, 13 Sep 2022 22:12:52 +0300 Subject: [PATCH 2/2] libjpegturbo simd extension update cmake flag --- 3rdparty/libjpeg-turbo/CMakeLists.txt | 5 ++--- CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/3rdparty/libjpeg-turbo/CMakeLists.txt b/3rdparty/libjpeg-turbo/CMakeLists.txt index e316e24822..d55dcdf962 100644 --- a/3rdparty/libjpeg-turbo/CMakeLists.txt +++ b/3rdparty/libjpeg-turbo/CMakeLists.txt @@ -63,7 +63,7 @@ OCV_OPTION(ENABLE_LIBJPEG_TURBO_SIMD "Include SIMD extensions for libjpeg-turbo, option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE) option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE) set(WITH_SIMD 1) -set(IS_LIBJPEG_TURBO_SIMD_AVAILABLE 0 PARENT_SCOPE) +set(HAVE_LIBJPEG_TURBO_SIMD 0 PARENT_SCOPE) include(CheckCSourceCompiles) include(CheckIncludeFiles) @@ -185,7 +185,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") endif() endif() -message(STATUS ${WITH_LIBJPEG_TURBO_SIMD}) if(ENABLE_LIBJPEG_TURBO_SIMD) add_subdirectory(src/simd) if(NEON_INTRINSICS) @@ -197,7 +196,7 @@ endif() if(WITH_SIMD) message(STATUS "SIMD extensions: ${CPU_TYPE} (WITH_SIMD = ${WITH_SIMD})") - set(IS_LIBJPEG_TURBO_SIMD_AVAILABLE 1 PARENT_SCOPE) + set(HAVE_LIBJPEG_TURBO_SIMD 1 PARENT_SCOPE) if(MSVC_IDE OR XCODE) set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1) endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 129cf0aae2..2bc79cc2f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1343,7 +1343,7 @@ if(WITH_JPEG OR HAVE_JPEG) status(" JPEG:" "build-${JPEG_LIBRARY} (ver ${JPEG_LIB_VERSION})") if(ENABLE_LIBJPEG_TURBO_SIMD) status(" SIMD Support Request:" "YES") - if(IS_LIBJPEG_TURBO_SIMD_AVAILABLE) + if(HAVE_LIBJPEG_TURBO_SIMD) status(" SIMD Support:" "YES") else() status(" SIMD Support:" "NO")