Skip to content

Commit

Permalink
Jsonifier Release v0.9.6
Browse files Browse the repository at this point in the history
-Implemented an AlignedAllocator class for increased performance.
-Added a string of uint8_ts that is aligned to 32-bytes for working with the to-be-parsed json data, for increased performance as a result of using aligned AVX-Loading functions.
-Updated the CMakeLists.txt file.
-Updating to fix various compiler warnings.
-Switched from using indices into the string to pointers into the string, for iterating the Json data.
-Removing instances of C++ aliasing.
-Updated the Pair class to support structured binding calls.
  • Loading branch information
RealTimeChris committed Aug 17, 2023
1 parent 6635ae8 commit c0ceec8
Show file tree
Hide file tree
Showing 32 changed files with 2,181 additions and 1,329 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/CLANG_17 - MacOS.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Build-and-Test-CLANG

on:
push:
branches:
- main
- dev

jobs:
Build:
runs-on: macos-latest

strategy:
fail-fast: false
matrix:
clang: [17]
build_type: [Debug, Release]
std: [20]

steps:
- uses: actions/checkout@v3

- name: Install Clang17
run: |
brew install llvm
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile
- name: Configure CMake
working-directory: Tests
run: |
cmake -S . -B ./Build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang-16 -DGITHUB_BRANCH_TYPE=${{github.ref}}
- name: Build the Test
working-directory: Tests/Build
run: |
cmake --build . --config=${{matrix.build_type}}
- name: Run the Test
working-directory: Tests/Build
run: |
./Json-Performance
12 changes: 1 addition & 11 deletions .github/workflows/CLANG_17.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,11 @@ jobs:
matrix:
clang: [17]
build_type: [Debug, Release]
std: [23]
std: [20]

steps:
- uses: actions/checkout@v3

- name: Update Vcpkg and install other dependencies.
run: |
sudo apt-get update --fix-missing
sudo apt-get upgrade --fix-missing
cd /usr/local/share/vcpkg
./bootstrap-vcpkg.sh
git stash
git pull
vcpkg update
- name: Install Clang17
run: |
sudo apt remove clang-14
Expand Down
12 changes: 1 addition & 11 deletions .github/workflows/GCC_12.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,14 @@ jobs:
matrix:
gcc: [12]
build_type: [Debug, Release]
std: [23]
std: [20]
env:
CC: gcc-${{matrix.gcc}}
CXX: g++-${{matrix.gcc}}

steps:
- uses: actions/checkout@v3

- name: Update Vcpkg and install other dependencies.
run: |
sudo apt-get update --fix-missing
sudo apt-get upgrade --fix-missing
cd /usr/local/share/vcpkg
./bootstrap-vcpkg.sh
git stash
git pull
vcpkg update
- name: Configure CMake
working-directory: Tests
run: |
Expand Down
11 changes: 1 addition & 10 deletions .github/workflows/MSVC_2022.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,17 @@ jobs:
matrix:
msvc: [2022]
build_type: [Debug, Release]
std: [23]
std: [20]

steps:
- uses: actions/checkout@v3
- uses: ilammy/[email protected]

- name: Append the directory of 'vcvarsall.bat' to PATH environment variable
uses: myci-actions/export-env-var-powershell@1
with:
name: PATH
value: $env:PATH;C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build

- name: Update Vcpkg and install other dependencies.
run: |
cd C:/vcpkg
./bootstrap-vcpkg.bat
git stash
git pull
vcpkg update
- name: Configure CMake
working-directory: Tests
run: |
Expand Down
18 changes: 8 additions & 10 deletions CMake/DetectArchitecture.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ function(check_instruction_set INSTRUCTION_SET_NAME INSTRUCTION_SET_FLAG INSTRUC
set(CMAKE_REQUIRED_FLAGS "${INSTRUCTION_SET_FLAG}")
CHECK_CXX_SOURCE_RUNS("${INSTRUCTION_SET_CODE}" "${INSTRUCTION_SET_NAME}")
if(${INSTRUCTION_SET_NAME})
math(EXPR AVX_TYPE "${AVX_TYPE} + 1")
set(AVX_TYPE "${AVX_TYPE}" PARENT_SCOPE)
set(AVX_TYPE "${INSTRUCTION_SET_NAME}" PARENT_SCOPE)
set(AVX_FLAG "${INSTRUCTION_SET_FLAG}" PARENT_SCOPE)
set(AVX_NAME "${INSTRUCTION_SET_NAME}" PARENT_SCOPE)
else()
Expand All @@ -27,22 +26,21 @@ endfunction()

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(INSTRUCTION_SETS
"AVX?/arch:AVX?auto result = _mm_testz_ps(__m128{}, __m128{})"
"AVX2?/arch:AVX2?auto result = _mm256_extract_epi64(__m256i{}, 0)"
"AVX512?/arch:AVX512?auto result = _mm512_add_ps(__m512i{}, __m512i{}).auto result2 = _mm512_cmplt_epu8_mask(__m512i{}, __m512i{})"
"T_AVX?/arch:AVX?auto result = _mm_testz_ps(__m128{}, __m128{})"
"T_AVX2?/arch:AVX2?auto result = _mm256_extract_epi64(__m256i{}, 0)"
"T_AVX512?/arch:AVX512?auto result = _mm512_add_ps(__m512i{}, __m512i{}).auto result2 = _mm512_cmplt_epu8_mask(__m512i{}, __m512i{}).char newArray[64]{}.auto result = _mm_loadu_epi64(newArray)"
)
else()
set(INSTRUCTION_SETS
"AVX?-mavx.-mpclmul.-mbmi?auto result = _mm_testz_ps(__m128{}, __m128{})"
"AVX2?-mavx2.-mavx.-mpclmul.-mbmi?auto result = _mm256_extract_epi64(__m256i{}, 0)"
"AVX512?-mavx512bw.-mavx512f.-mavx2.-mavx.-mpclmul.-mbmi?auto result = _mm512_add_ps(__m512i{}, __m512i{}).auto result2 = _mm512_cmplt_epu8_mask(__m512i{}, __m512i{})"
"T_AVX?-mavx.-mpclmul.-mbmi?auto result = _mm_testz_ps(__m128{}, __m128{})"
"T_AVX2?-mavx2.-mavx.-mpclmul.-mbmi?auto result = _mm256_extract_epi64(__m256i{}, 0)"
"T_AVX512?-mavx512bw.-avx512vl.-mavx512f.-mavx2.-mavx.-mpclmul.-mbmi?auto result = _mm512_add_ps(__m512i{}, __m512i{}).auto result2 = _mm512_cmplt_epu8_mask(__m512i{}, __m512i{}).char newArray[64]{}.auto result = _mm_loadu_epi64(newArray)"
)
endif()

set(CMAKE_REQUIRED_FLAGS_SAVE "${CMAKE_REQUIRED_FLAGS}")

set(AVX_NAME "Fallback")
set(AVX_TYPE 124)
set(AVX_NAME "T_Fallback")

foreach(INSTRUCTION_SET IN LISTS INSTRUCTION_SETS)
string(REPLACE "?" ";" CURRENT_LIST "${INSTRUCTION_SET}")
Expand Down
21 changes: 11 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ project(
LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 20)

add_library("${PROJECT_NAME}" INTERFACE)

add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")

file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Include/jsonifier/*.hpp")

include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/DetectArchitecture.cmake")
if(NOT DEFINED AVX_TYPE)
include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/DetectArchitecture.cmake")
endif()

set_target_properties(
"${PROJECT_NAME}" PROPERTIES
Expand All @@ -57,15 +61,18 @@ target_include_directories(

target_compile_definitions(
"${PROJECT_NAME}" INTERFACE
"AVX_TYPE=${AVX_TYPE}"
"${AVX_TYPE}"
)

target_compile_options(
"${PROJECT_NAME}" INTERFACE
"$<$<CXX_COMPILER_ID:MSVC>:$<$<STREQUAL:${ASAN_ENABLED},TRUE>:/fsanitize=address>>"
"$<$<CXX_COMPILER_ID:MSVC>:$<$<STREQUAL:${ASAN_ENABLED},TRUE>:/Zi>>"
"$<$<CXX_COMPILER_ID:MSVC>:$<$<STREQUAL:${ASAN_ENABLED},TRUE>:/EHsc>>"
"$<$<CXX_COMPILER_ID:MSVC>:/std:c++latest>"
"$<$<CXX_COMPILER_ID:CLANG>:-Wextra>"
"$<$<CXX_COMPILER_ID:CLANG>:-Wall>"
"$<$<CXX_COMPILER_ID:GNU>:-Wextra>"
"$<$<CXX_COMPILER_ID:GNU>:-Wall>"
"$<$<CXX_COMPILER_ID:MSVC>:/W4>"
"${AVX_FLAG}"
)

Expand All @@ -74,12 +81,6 @@ target_link_options(
"$<$<CXX_COMPILER_ID:GNU>:$<$<STREQUAL:${ASAN_ENABLED},TRUE>:-fsanitize=address>>"
)

target_compile_features(
"${PROJECT_NAME}" INTERFACE
"$<$<CXX_COMPILER_ID:GNU>:cxx_std_23>"
"$<$<CXX_COMPILER_ID:CLANG>:cxx_std_23>"
)

set(CONFIG_FILE_NAME "${PROJECT_NAME}Config.cmake")
set(EXPORTED_TARGETS_NAME "${PROJECT_NAME}Targets")
set(EXPORTED_TARGETS_FILE_NAME "${EXPORTED_TARGETS_NAME}.cmake")
Expand Down
94 changes: 94 additions & 0 deletions Include/jsonifier/Allocator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
MIT License
Copyright (c) 2023 RealTimeChris
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/// https://github.com/RealTimeChris/Jsonifier
/// Feb 3, 2023
#pragma once

#include <cstdint>
#include <utility>
#include <memory>

#if defined(_MSC_VER)
#define ALIGNED_ALLOC(size, alignment) _aligned_malloc(size, alignment)
#define ALIGNED_FREE(ptr) _aligned_free(ptr)
#else
#define ALIGNED_ALLOC(size, alignment) aligned_alloc(alignment, size)
#define ALIGNED_FREE(ptr) free(ptr)
#endif

namespace JsonifierInternal {

template<typename ValueType, uint64_t Alignment = alignof(ValueType)> class AlignedAllocator {
public:
using value_type = ValueType;
using pointer = value_type*;
using size_type = uint64_t;

inline pointer allocate(size_type n) {
if (n == 0) {
return nullptr;
}

return static_cast<pointer>(ALIGNED_ALLOC(n * sizeof(ValueType), Alignment < 32 ? 32 : Alignment));
}

inline void deallocate(pointer p, size_type) {
if (p) {
ALIGNED_FREE(p);
}
}

template<typename... Args> inline void construct(pointer p, Args&&... args) {
new (p) value_type(std::forward<Args>(args)...);
}

inline void destroy(pointer p) {
p->~value_type();
}
};

template<typename ValueType> class AllocWrapper : public AlignedAllocator<ValueType> {
public:
using value_type = ValueType;
using pointer = value_type*;
using size_type = uint64_t;
using allocator = AlignedAllocator<value_type>;
using allocator_traits = std::allocator_traits<allocator>;

inline pointer allocate(size_type count) noexcept {
return allocator_traits::allocate(*this, count);
}

inline void deallocate(pointer ptr, size_type count) noexcept {
allocator_traits::deallocate(*this, ptr, count);
}

template<typename... Args> inline void construct(pointer ptr, Args&&... args) noexcept {
allocator_traits::construct(*this, ptr, std::forward<Args>(args)...);
}

inline void destroy(pointer ptr) noexcept {
allocator_traits::destroy(*this, ptr);
}
};

}
Loading

0 comments on commit c0ceec8

Please sign in to comment.