2020-04-23 08:25:45 +08:00
|
|
|
if (NOT CMAKE_BUILD_TYPE)
|
|
|
|
message(STATUS "No build type selected, default to Release")
|
|
|
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
|
|
|
|
endif()
|
|
|
|
|
|
|
|
if(MSVC)
|
|
|
|
option(SIMDJSON_BUILD_STATIC "Build a static library" ON) # turning it on disables the production of a dynamic library
|
|
|
|
else()
|
|
|
|
option(SIMDJSON_BUILD_STATIC "Build a static library" OFF) # turning it on disables the production of a dynamic library
|
|
|
|
option(SIMDJSON_USE_LIBCPP "Use the libc++ library" OFF)
|
|
|
|
endif()
|
2020-06-01 08:34:06 +08:00
|
|
|
option(SIMDJSON_COMPETITION "Compile competitive benchmarks" ON)
|
|
|
|
|
2020-04-30 03:59:52 +08:00
|
|
|
option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" ON)
|
2020-04-23 08:25:45 +08:00
|
|
|
|
|
|
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake")
|
|
|
|
|
|
|
|
# We compile tools, tests, etc. with C++ 17. Override yourself if you need on a target.
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
|
|
set(CMAKE_MACOSX_RPATH OFF)
|
|
|
|
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
|
|
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
|
|
|
|
|
|
# LTO seems to create all sorts of fun problems. Let us
|
|
|
|
# disable temporarily.
|
|
|
|
#include(CheckIPOSupported)
|
|
|
|
#check_ipo_supported(RESULT ltoresult)
|
|
|
|
#if(ltoresult)
|
|
|
|
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
|
|
|
#endif()
|
|
|
|
|
|
|
|
#
|
|
|
|
# Flags used by exes and by the simdjson library (project-wide flags)
|
|
|
|
#
|
|
|
|
add_library(simdjson-flags INTERFACE)
|
2020-05-02 09:08:47 +08:00
|
|
|
add_library(simdjson-internal-flags INTERFACE)
|
2020-05-03 07:48:29 +08:00
|
|
|
target_link_libraries(simdjson-internal-flags INTERFACE simdjson-flags)
|
|
|
|
|
2020-04-23 08:25:45 +08:00
|
|
|
if(MSVC)
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_options(simdjson-internal-flags INTERFACE /WX /W3 /sdl)
|
2020-04-23 08:25:45 +08:00
|
|
|
else()
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_options(simdjson-internal-flags INTERFACE -fPIC)
|
2020-04-23 08:25:45 +08:00
|
|
|
if (NOT SIMDJSON_GOOGLE_BENCHMARKS) # Google Benchmark can't be compiled without warnings with -Weffc++
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_options(simdjson-internal-flags INTERFACE -Weffc++)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_options(simdjson-internal-flags INTERFACE -Werror -Wall -Wextra -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wno-sign-conversion)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
|
|
|
|
# Optional flags
|
|
|
|
option(SIMDJSON_IMPLEMENTATION_HASWELL "Include the haswell implementation" ON)
|
|
|
|
if(NOT SIMDJSON_IMPLEMENTATION_HASWELL)
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_HASWELL=0)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
option(SIMDJSON_IMPLEMENTATION_WESTMERE "Include the westmere implementation" ON)
|
|
|
|
if(NOT SIMDJSON_IMPLEMENTATION_WESTMERE)
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_WESTMERE=0)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
option(SIMDJSON_IMPLEMENTATION_ARM64 "Include the arm64 implementation" ON)
|
|
|
|
if(NOT SIMDJSON_IMPLEMENTATION_ARM64)
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_ARM64=0)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
option(SIMDJSON_IMPLEMENTATION_FALLBACK "Include the fallback implementation" ON)
|
|
|
|
if(NOT SIMDJSON_IMPLEMENTATION_FALLBACK)
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_FALLBACK=0)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
|
|
|
|
option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON)
|
|
|
|
if(NOT SIMDJSON_EXCEPTIONS)
|
|
|
|
message(STATUS "simdjson exception interface turned off. Code that does not check error codes will not compile.")
|
2020-05-02 09:08:47 +08:00
|
|
|
target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_EXCEPTIONS=0)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
|
|
|
|
option(SIMDJSON_ENABLE_THREADS "Enable threaded operation" ON)
|
|
|
|
if(SIMDJSON_ENABLE_THREADS)
|
2020-04-30 04:47:36 +08:00
|
|
|
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
|
|
|
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
2020-06-06 09:01:41 +08:00
|
|
|
find_package(Threads REQUIRED)
|
Using a worker instead of a thread per batch (#920)
In the parse_many function, we have one thread doing the stage 1, while the main thread does stage 2. So if stage 1 and stage 2 take half the time, the parse_many could run at twice the speed. It is unlikely to do so. Still, we see benefits of about 40% due to threading.
To achieve this interleaving, we load the data in batches (blocks) of some size. In the current code (master), we create a new thread for each batch. Thread creation is expensive so our approach only works over sizeable batches. This PR improves things and makes parse_many faster when using small batches.
This fixes our parse_stream benchmark which is just busted.
This replaces the one-thread per batch routine by a worker object that reuses the same thread. In benchmarks, this allows us to get the same maximal speed, but with smaller processing blocks. It does not help much with larger blocks because the cost of the thread create gets amortized efficiently.
This PR makes parse_many beneficial over small datasets. It also makes us less dependent on the thread creation time.
Unfortunately, it is going to be difficult to say anything definitive in general. The cost of creating a thread varies widely depending on the OS. On some systems, it might be cheap, in others very expensive. It should be expected that the new code will depend less drastically on the performances of the underlying system, since we create juste one thread.
Co-authored-by: John Keiser <john@johnkeiser.com>
Co-authored-by: Daniel Lemire <lemire@gmai.com>
2020-06-13 04:51:18 +08:00
|
|
|
target_link_libraries(simdjson-flags INTERFACE Threads::Threads)
|
2020-06-06 09:01:41 +08:00
|
|
|
target_link_libraries(simdjson-flags INTERFACE ${CMAKE_THREAD_LIBS_INIT})
|
|
|
|
target_compile_options(simdjson-flags INTERFACE ${CMAKE_THREAD_LIBS_INIT})
|
Using a worker instead of a thread per batch (#920)
In the parse_many function, we have one thread doing the stage 1, while the main thread does stage 2. So if stage 1 and stage 2 take half the time, the parse_many could run at twice the speed. It is unlikely to do so. Still, we see benefits of about 40% due to threading.
To achieve this interleaving, we load the data in batches (blocks) of some size. In the current code (master), we create a new thread for each batch. Thread creation is expensive so our approach only works over sizeable batches. This PR improves things and makes parse_many faster when using small batches.
This fixes our parse_stream benchmark which is just busted.
This replaces the one-thread per batch routine by a worker object that reuses the same thread. In benchmarks, this allows us to get the same maximal speed, but with smaller processing blocks. It does not help much with larger blocks because the cost of the thread create gets amortized efficiently.
This PR makes parse_many beneficial over small datasets. It also makes us less dependent on the thread creation time.
Unfortunately, it is going to be difficult to say anything definitive in general. The cost of creating a thread varies widely depending on the OS. On some systems, it might be cheap, in others very expensive. It should be expected that the new code will depend less drastically on the performances of the underlying system, since we create juste one thread.
Co-authored-by: John Keiser <john@johnkeiser.com>
Co-authored-by: Daniel Lemire <lemire@gmai.com>
2020-06-13 04:51:18 +08:00
|
|
|
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_THREADS_ENABLED=1)
|
2020-04-23 08:25:45 +08:00
|
|
|
endif()
|
|
|
|
|
|
|
|
option(SIMDJSON_SANITIZE "Sanitize addresses" OFF)
|
|
|
|
if(SIMDJSON_SANITIZE)
|
|
|
|
target_compile_options(simdjson-flags INTERFACE -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all)
|
|
|
|
target_link_libraries(simdjson-flags INTERFACE -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all)
|
|
|
|
|
|
|
|
# Ubuntu bug for GCC 5.0+ (safe for all versions)
|
|
|
|
if (CMAKE_COMPILER_IS_GNUCC)
|
|
|
|
target_link_libraries(simdjson-flags INTERFACE -fuse-ld=gold)
|
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
|
|
|
|
if(SIMDJSON_USE_LIBCPP)
|
|
|
|
target_link_libraries(simdjson-flags INTERFACE -stdlib=libc++ -lc++abi)
|
|
|
|
# instead of the above line, we could have used
|
|
|
|
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")
|
|
|
|
# The next line is needed empirically.
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
|
|
|
# we update CMAKE_SHARED_LINKER_FLAGS, this gets updated later as well
|
|
|
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lc++abi")
|
|
|
|
endif(SIMDJSON_USE_LIBCPP)
|
|
|
|
|
|
|
|
# prevent shared libraries from depending on Intel provided libraries
|
|
|
|
if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
|
|
|
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel")
|
|
|
|
endif()
|
|
|
|
|
2020-04-30 07:06:19 +08:00
|
|
|
install(TARGETS simdjson-flags EXPORT simdjson-config)
|
2020-05-02 09:08:47 +08:00
|
|
|
install(TARGETS simdjson-internal-flags EXPORT simdjson-config)
|