Skip to content

Commit

Permalink
feat: improving parser performance using SSE Instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
helintongh committed Jul 20, 2023
1 parent 1e1cdb9 commit 063cf9c
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
17 changes: 17 additions & 0 deletions cmake/develop.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ if(ENABLE_CLIENT_SSL)
add_definitions(-DCINATRA_ENABLE_CLIENT_SSL)
endif()


if(ENABLE_SIMD STREQUAL "SSE42" OR ENABLE_SIMD STREQUAL "AVX2" OR ENABLE_SIMD STREQUAL "AARCH64")
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64")
message(STATUS "Build with simd in aarch64")
add_definitions(-DCINATRA_AARCH64)
elseif (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
message(STATUS "Build with simd in X86_64")
if (ENABLE_SIMD STREQUAL "SSE42")
message(STATUS "Build with SSE4.2 ISA")
add_definitions(-DCINATRA_SSE)
elseif (ENABLE_SIMD STREQUAL "AVX2")
message(STATUS "Build with AVX2 ISA")
add_definitions(-DCINATRA_AVX2)
endif ()
endif ()
endif()

add_definitions(-DASIO_STANDALONE)

if (ENABLE_SSL)
Expand Down
48 changes: 46 additions & 2 deletions include/cinatra/picohttpparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
#include <stddef.h>
#include <string.h>

#ifdef CINATRA_SSE
#ifdef _MSC_VER
#include <nmmintrin.h>
#else
#include <x86intrin.h>
#endif
#endif

#include <sys/types.h>

#ifdef _MSC_VER
#define ssize_t intptr_t
#endif
Expand Down Expand Up @@ -163,18 +173,52 @@ static const char *findchar_fast(const char *buf, const char *buf_end,
const char *ranges, int ranges_size,
int *found) {
*found = 0;
#ifdef CINATRA_SSE
if (likely(buf_end - buf >= 16)) {
__m128i ranges16 = _mm_loadu_si128((const __m128i *)ranges);

size_t left = (buf_end - buf) & ~15;
do {
__m128i b16 = _mm_loadu_si128((const __m128i *)buf);
int r = _mm_cmpestri(
ranges16, ranges_size, b16, 16,
_SIDD_LEAST_SIGNIFICANT | _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS);
if (unlikely(r != 16)) {
buf += r;
*found = 1;
break;
}
buf += 16;
left -= 16;
} while (likely(left != 0));
}
#else
/* suppress unused parameter warning */
(void)buf_end;
(void)ranges;
(void)ranges_size;
#endif
return buf;
}

static const char *get_token_to_eol(const char *buf, const char *buf_end,
const char **token, size_t *token_len,
int *ret) {
const char *token_start = buf;

#ifdef CINATRA_SSE
static const char ranges1[] =
"\0\010"
/* allow HT */
"\012\037"
/* allow SP and up to but not including DEL */
"\177\177"
/* allow chars w. MSB set */
;
int found;
buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found);
if (found)
goto FOUND_CTL;
#else
/* find non-printable char within the next 8 bytes, this is the hottest code;
* manually inlined */
while (likely(buf_end - buf >= 8)) {
Expand All @@ -201,7 +245,7 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end,
}
++buf;
}

#endif
for (;; ++buf) {
CHECK_EOF();
if (unlikely(!IS_PRINTABLE_ASCII(*buf))) {
Expand Down
15 changes: 15 additions & 0 deletions press_tool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ endif()
if (ENABLE_GZIP)
target_link_libraries(${project_name} ${ZLIB_LIBRARIES})
endif()

if (ENABLE_SIMD STREQUAL "AARCH64")
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64")
#TODO
endif ()
elseif (ENABLE_SIMD STREQUAL "SSE42")
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
target_link_libraries(${project_name} sse4.2)
endif ()
elseif (ENABLE_SIMD STREQUAL "AVX2")
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
target_link_libraries(${project_name} avx2)
endif ()
endif ()

install(TARGETS ${project_name} DESTINATION include)

set(unittest_press_tool test_cinatra_press_tool)
Expand Down

0 comments on commit 063cf9c

Please sign in to comment.