lib: optionally use crc-fast-rust library

Typically, this CRC16 implementation is even faster, as it uses
32 bit SSE calculations and then trucates the output to 16 bits.
Also comes with AVX-512 support.

https://github.com/awesomized/crc-fast-rust
This commit is contained in:
Steve Markgraf 2025-12-25 00:40:38 +01:00
parent 359f141789
commit a71d50969d
4 changed files with 93 additions and 20 deletions

View file

@ -19,14 +19,8 @@
######################################################################## ########################################################################
# Project setup # Project setup
######################################################################## ########################################################################
cmake_minimum_required(VERSION 3.10.0) cmake_minimum_required(VERSION 3.12.0)
project(hsdaoh C)
# workaround for https://gitlab.kitware.com/cmake/cmake/issues/16967
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
project(hsdaoh)
else()
project(hsdaoh C)
endif()
#select the release build type by default to get optimization flags #select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
@ -62,14 +56,14 @@ elseif(MSVC14 OR MSVC14)
ADD_DEFINITIONS(-D_TIMESPEC_DEFINED) ADD_DEFINITIONS(-D_TIMESPEC_DEFINED)
endif() endif()
# Enable SIMD instructions on x86
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64|i386|i686")
add_compile_options(-mpclmul -msse4.1)
endif()
######################################################################## ########################################################################
# CRC SIMD specific setup # CRC SIMD specific setup
######################################################################## ########################################################################
# Enable SIMD instructions on x86
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64|i386|i686")
add_compile_options(-mpclmul -mssse3)
endif()
# Enable crypto extensions on ARM64 # Enable crypto extensions on ARM64
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
# Check if using GCC or Clang # Check if using GCC or Clang
@ -121,6 +115,8 @@ else()
set(LIBFLAC_INCLUDE_DIRS "" CACHE STRING "manual FLAC includepath") set(LIBFLAC_INCLUDE_DIRS "" CACHE STRING "manual FLAC includepath")
endif() endif()
find_package(CRCFAST)
if(MSVC) if(MSVC)
set(THREADS_PTHREADS_LIBRARY "" CACHE STRING "manual pthread-win32 path") set(THREADS_PTHREADS_LIBRARY "" CACHE STRING "manual pthread-win32 path")
set(THREADS_PTHREADS_INCLUDE_DIR "" CACHE STRING "manual pthread-win32 includepath") set(THREADS_PTHREADS_INCLUDE_DIR "" CACHE STRING "manual pthread-win32 includepath")

View file

@ -0,0 +1,20 @@
find_path(CRCFAST_INCLUDE_DIR
NAMES libcrc_fast.h
)
find_library(CRCFAST_LIBRARY
NAMES crc_fast
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CRCFAST
REQUIRED_VARS CRCFAST_LIBRARY CRCFAST_INCLUDE_DIR
)
if(CRCFAST_FOUND)
add_library(CRCFAST::CRCFAST UNKNOWN IMPORTED)
set_target_properties(CRCFAST::CRCFAST PROPERTIES
IMPORTED_LOCATION "${CRCFAST_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${CRCFAST_INCLUDE_DIR}"
)
endif()

View file

@ -15,11 +15,38 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
set(HSDAOH_COMMON_SOURCES
libhsdaoh.c
format_convert.c
iqconverter_float.c
)
if(NOT CRCFAST_FOUND)
list(APPEND HSDAOH_COMMON_SOURCES
crcspeed.c
crc16speed.c
crc_simd.c
)
endif()
######################################################################## ########################################################################
# Setup shared library variant # Setup shared library variant
######################################################################## ########################################################################
add_library(hsdaoh SHARED libhsdaoh.c format_convert.c iqconverter_float.c crcspeed.c crc16speed.c crc_simd.c) add_library(hsdaoh SHARED ${HSDAOH_COMMON_SOURCES})
target_link_libraries(hsdaoh ${LIBUSB_LIBRARIES} ${LIBUVC_LIBRARIES} ${THREADS_PTHREADS_LIBRARY})
target_link_libraries(hsdaoh
${LIBUSB_LIBRARIES}
${LIBUVC_LIBRARIES}
${THREADS_PTHREADS_LIBRARY}
)
if(CRCFAST_FOUND)
target_link_libraries(hsdaoh CRCFAST::CRCFAST)
target_compile_definitions(hsdaoh PRIVATE HAVE_CRCFAST=1)
else()
target_compile_definitions(hsdaoh PRIVATE HAVE_CRCFAST=0)
endif()
target_include_directories(hsdaoh PUBLIC target_include_directories(hsdaoh PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include> # <prefix>/include $<INSTALL_INTERFACE:include> # <prefix>/include
@ -36,8 +63,22 @@ generate_export_header(hsdaoh)
######################################################################## ########################################################################
# Setup static library variant # Setup static library variant
######################################################################## ########################################################################
add_library(hsdaoh_static STATIC libhsdaoh.c format_convert.c iqconverter_float.c) add_library(hsdaoh_static STATIC ${HSDAOH_COMMON_SOURCES})
target_link_libraries(hsdaoh m ${LIBUSB_LIBRARIES} ${LIBUVC_LIBRARIES} ${THREADS_PTHREADS_LIBRARY})
target_link_libraries(hsdaoh_static
m
${LIBUSB_LIBRARIES}
${LIBUVC_LIBRARIES}
${THREADS_PTHREADS_LIBRARY}
)
if(CRCFAST_FOUND)
target_link_libraries(hsdaoh_static CRCFAST::CRCFAST)
target_compile_definitions(hsdaoh_static PRIVATE HAVE_CRCFAST=1)
else()
target_compile_definitions(hsdaoh_static PRIVATE HAVE_CRCFAST=0)
endif()
target_include_directories(hsdaoh_static PUBLIC target_include_directories(hsdaoh_static PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include> # <prefix>/include $<INSTALL_INTERFACE:include> # <prefix>/include

View file

@ -41,14 +41,19 @@
#include <libusb.h> #include <libusb.h>
#include <libuvc/libuvc.h> #include <libuvc/libuvc.h>
#if HAVE_CRCFAST
#include <libcrc_fast.h>
#else
#include <crc16speed.h>
#include <crc_simd.h>
#endif
#include <iqconverter_float.h> #include <iqconverter_float.h>
#include <filters.h> #include <filters.h>
#include <hsdaoh.h> #include <hsdaoh.h>
#include <hsdaoh_private.h> #include <hsdaoh_private.h>
#include <format_convert.h> #include <format_convert.h>
#include <crc16speed.h>
#include <crc_simd.h>
#define DEFAULT_BUFFERS 96 #define DEFAULT_BUFFERS 96
@ -494,8 +499,10 @@ int hsdaoh_open(hsdaoh_dev_t **out_dev, uint32_t index)
dev->cnv_f1 = iqconverter_float_create(HB_KERNEL_FLOAT, HB_KERNEL_FLOAT_LEN); dev->cnv_f1 = iqconverter_float_create(HB_KERNEL_FLOAT, HB_KERNEL_FLOAT_LEN);
dev->cnv_f2 = iqconverter_float_create(HB_KERNEL_FLOAT, HB_KERNEL_FLOAT_LEN); dev->cnv_f2 = iqconverter_float_create(HB_KERNEL_FLOAT, HB_KERNEL_FLOAT_LEN);
#if HAVE_CRCFAST == 0
crc16speed_init(); crc16speed_init();
crc16_simd_init(); crc16_simd_init();
#endif
found: found:
*out_dev = dev; *out_dev = dev;
@ -692,6 +699,15 @@ inline int hsdaoh_check_idle_cnt(hsdaoh_dev_t *dev, uint16_t *buf, size_t length
return idle_counter_errors; return idle_counter_errors;
} }
inline uint16_t crc16(uint8_t *buf, unsigned int len)
{
#if HAVE_CRCFAST
return (uint16_t)crc_fast_checksum(Crc16Ibm3740, (const char *)buf, len);
#else
return crc16_simd(0xffff, buf, len);
#endif
}
/* Extract the metadata stored in the upper 4 bits of the last word of each line */ /* Extract the metadata stored in the upper 4 bits of the last word of each line */
inline void hsdaoh_extract_metadata(uint8_t *data, metadata_t *metadata, unsigned int width) inline void hsdaoh_extract_metadata(uint8_t *data, metadata_t *metadata, unsigned int width)
{ {
@ -775,7 +791,7 @@ void hsdaoh_process_frame(hsdaoh_dev_t *dev, uint8_t *data, int size)
frame_errors++; frame_errors++;
dev->last_crc[1] = dev->last_crc[0]; dev->last_crc[1] = dev->last_crc[0];
dev->last_crc[0] = crc16_simd(0xffff, line_dat, dev->width * sizeof(uint16_t)); dev->last_crc[0] = crc16(line_dat, dev->width * sizeof(uint16_t));
} }
if ((payload_len > 0) && dev->stream_synced) { if ((payload_len > 0) && dev->stream_synced) {