Skip to content

Commit 50514ec

Browse files
authored
feat: support neon, sse simd and dynamic dispatch (bytedance#56)
# Main changes - support both static dispatch and dynamic dispatch - support neon and sse architecture
1 parent e3038ea commit 50514ec

60 files changed

Lines changed: 3955 additions & 1193 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ jobs:
77
strategy:
88
fail-fast: false
99
matrix:
10-
llvm_version:
11-
- '11'
12-
- '13.0.0'
13-
- '15'
14-
tool:
15-
- 'cmake'
16-
- 'bazel'
10+
llvm_version: ['11', '13.0.0', '15']
11+
tool: ['cmake', 'bazel']
12+
arch: [westmere, haswell]
13+
exclude:
14+
- tool: 'cmake'
15+
arch: westmere
1716
env:
1817
CC: clang
1918
CXX: clang++
@@ -38,10 +37,10 @@ jobs:
3837
with:
3938
cmake-version: "latest"
4039

41-
- name: Run Test Use Bazel
40+
- name: Run ${{ matrix.arch }} Test Use Bazel
4241
if: matrix.tool == 'bazel'
4342
run : |
44-
bash ./scripts/unittest.sh -c
43+
bash ./scripts/unittest.sh -c --arch=${{ matrix.arch }}
4544
4645
- name: Run Test Use CMake
4746
if: matrix.tool == 'cmake'
@@ -53,12 +52,19 @@ jobs:
5352
strategy:
5453
fail-fast: false
5554
matrix:
56-
gcc_version:
57-
- '9'
58-
- '12'
59-
tool:
60-
- 'cmake'
61-
- 'bazel'
55+
gcc_version: ['9', '12']
56+
tool: ['cmake', 'bazel']
57+
arch: [westmere, haswell]
58+
dispatch: [static, dynamic]
59+
exclude:
60+
- tool: 'bazel'
61+
arch: haswell
62+
dispatch: dynamic
63+
- tool: 'cmake'
64+
dispatch: dynamic
65+
- tool: 'cmake'
66+
arch: westmere
67+
6268
env:
6369
CC: gcc-${{ matrix.gcc_version }}
6470
CXX: g++-${{ matrix.gcc_version}}
@@ -82,10 +88,10 @@ jobs:
8288
with:
8389
cmake-version: "latest"
8490

85-
- name: Run Test Use Bazel
91+
- name: Run ${{ matrix.arch }} ${{ matrix.dispatch }} Test Use Bazel
8692
if: matrix.tool == 'bazel'
8793
run : |
88-
bash ./scripts/unittest.sh -g
94+
bash ./scripts/unittest.sh -g --arch=${{ matrix.arch }} --dispatch=${{ matrix.dispatch }}
8995
9096
- name: Run Test Use CMake
9197
if: matrix.tool == 'cmake'

BUILD.bazel

Lines changed: 146 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,73 @@
11
package(default_visibility = ["//visibility:public"])
2+
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
23

34
common_copts = ['-mavx2', '-mbmi', '-mpclmul']
45
sanitize_copts = ['-fsanitize=address,undefined', '-fsanitize-recover=address']
56

7+
avx2_copts = ['-mavx2', '-mbmi', '-mpclmul']
8+
sse_copts = ['-msse', '-msse2', '-msse4.1', '-mpclmul']
9+
arm_copts = ['-march-armv8-a']
10+
benchmark_copts = ['-O3', '-DNDEBUG', '-std=c++17']
11+
static_dispatch_copts = []
12+
dynamic_dispatch_copts = ['-DSONIC_DYNAMIC_DISPATCH=1']
13+
no_san_linkopts = []
14+
gcc_san_linkopts = ['-lasan']
15+
clang_san_linkopts = ['-fsanitize-link-c++-runtime']
16+
17+
string_flag(
18+
name = "sonic_arch",
19+
build_setting_default = "haswell",
20+
)
21+
22+
string_flag(
23+
name = "sonic_dispatch",
24+
build_setting_default = "static",
25+
)
26+
27+
string_flag(
28+
name = "sonic_sanitizer",
29+
build_setting_default = "no",
30+
)
31+
32+
config_setting(
33+
name = "arm_build",
34+
flag_values = {":sonic_arch": "arm"},
35+
)
36+
37+
config_setting(
38+
name = "sse_build",
39+
flag_values = {":sonic_arch": "westmere"},
40+
)
41+
config_setting(
42+
name = "avx2_build",
43+
flag_values = {":sonic_arch": "haswell"},
44+
)
45+
46+
config_setting(
47+
name = "static_dispatch",
48+
flag_values = {":sonic_dispatch": "static"},
49+
)
50+
51+
config_setting(
52+
name = "dynamic_dispatch",
53+
flag_values = {":sonic_dispatch": "dynamic"},
54+
)
55+
56+
config_setting(
57+
name = "no_san",
58+
flag_values = {":sonic_sanitizer": "no"},
59+
)
60+
61+
config_setting(
62+
name = "gcc_san",
63+
flag_values = {":sonic_sanitizer": "gcc"},
64+
)
65+
66+
config_setting(
67+
name = "clang_san",
68+
flag_values = {":sonic_sanitizer": "clang"},
69+
)
70+
671
cc_library(
772
name = "string_view",
873
hdrs = glob(["include/thirdparty/**/*.h"]),
@@ -35,12 +100,21 @@ cc_binary(
35100
"@simdjson",
36101
"@jsoncpp//:jsoncpp",
37102
],
38-
copts = common_copts + ['-DNDEBUG', '-std=c++17'],
103+
# copts = common_copts + ['-DNDEBUG', '-std=c++17'],
104+
copts = select({
105+
"arm_build": arm_copts + benchmark_copts,
106+
"sse_build": sse_copts + benchmark_copts,
107+
"avx2_build": avx2_copts + benchmark_copts,
108+
}) +\
109+
select({
110+
"static_dispatch": static_dispatch_copts,
111+
"dynamic_dispatch": dynamic_dispatch_copts,
112+
}),
39113
linkopts = ['-lstdc++fs'],
40114
)
41115

42116
cc_test(
43-
name = "unittest-gcc",
117+
name = "unittest",
44118
srcs = glob([
45119
"tests/*.cpp",
46120
"include/sonic/*",
@@ -51,10 +125,49 @@ cc_test(
51125
"@gtest//:gtest_main",
52126
],
53127
data = glob([ "testdata/*.json"]),
128+
linkopts = [ '-lstdc++fs', '-fstack-protector-all',] +\
129+
select({
130+
"no_san": [],
131+
"gcc_san": sanitize_copts + gcc_san_linkopts,
132+
"clang_san": sanitize_copts + clang_san_linkopts,
133+
}),
134+
copts = [
135+
'-O3', '-g', '-UNDEBUG', '-std=c++14',
136+
'-fstack-protector-all',
137+
'-Iinclude', '-Wall', '-Wextra', '-Werror',
138+
] + \
139+
select({
140+
"no_san": [],
141+
"gcc_san": sanitize_copts,
142+
"clang_san": sanitize_copts,
143+
}) + \
144+
select({
145+
"arm_build": arm_copts + benchmark_copts,
146+
"sse_build": sse_copts + benchmark_copts,
147+
"avx2_build": avx2_copts + benchmark_copts,
148+
}) +\
149+
select({
150+
"static_dispatch": static_dispatch_copts,
151+
"dynamic_dispatch": dynamic_dispatch_copts,
152+
}),
153+
)
154+
155+
cc_test(
156+
name = "unittest-clang",
157+
srcs = glob([
158+
"tests/*.h",
159+
"tests/*.cpp",
160+
"include/sonic/*",
161+
"include/sonic/**/*",
162+
]),
163+
deps = [
164+
":string_view",
165+
"@gtest//:gtest_main",
166+
],
167+
data = glob([ "testdata/*.json"]),
54168
linkopts = sanitize_copts + [
55169
'-lstdc++fs',
56170
'-fstack-protector-all',
57-
'-lasan'
58171
],
59172
copts = common_copts + sanitize_copts + [
60173
'-O3', '-g', '-UNDEBUG', '-std=c++14',
@@ -64,14 +177,14 @@ cc_test(
64177
)
65178

66179
cc_test(
67-
name = "unittest-clang",
180+
name = "unittest-arm",
68181
srcs = glob([
69182
"tests/*.h",
70183
"tests/*.cpp",
71184
"include/sonic/*",
72185
"include/sonic/**/*",
73186
]),
74-
deps = [
187+
deps = [
75188
":string_view",
76189
"@gtest//:gtest_main",
77190
],
@@ -81,8 +194,33 @@ cc_test(
81194
'-fstack-protector-all',
82195
'-fsanitize-link-c++-runtime'
83196
],
84-
copts = common_copts + sanitize_copts + [
85-
'-O3', '-g', '-UNDEBUG', '-std=c++14',
197+
copts = sanitize_copts + [
198+
'-O3', '-g', '-UNDEBUG', '-std=c++14', '-march=armv8-a',
199+
'-fstack-protector-all',
200+
'-Iinclude', '-Wall', '-Wextra', '-Werror',
201+
],
202+
)
203+
204+
cc_test(
205+
name = "unittest-sse",
206+
srcs = glob([
207+
"tests/*.h",
208+
"tests/*.cpp",
209+
"include/sonic/*",
210+
"include/sonic/**/*",
211+
]),
212+
deps = [
213+
":string_view",
214+
"@gtest//:gtest_main",
215+
],
216+
data = glob([ "testdata/*.json"]),
217+
linkopts = sanitize_copts + [
218+
'-lstdc++fs',
219+
'-fstack-protector-all',
220+
'-fsanitize-link-c++-runtime'
221+
],
222+
copts = sanitize_copts + [
223+
'-O3', '-g', '-UNDEBUG', '-std=c++14', '-march=westmere',
86224
'-fstack-protector-all',
87225
'-Iinclude', '-Wall', '-Wextra', '-Werror',
88226
],
@@ -112,3 +250,4 @@ cc_test(
112250
'-fprofile-arcs', '-ftest-coverage',
113251
],
114252
)
253+

WORKSPACE

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
22
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
3+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
4+
5+
http_archive(
6+
name = "bazel_skylib",
7+
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
8+
urls = [
9+
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
10+
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
11+
],
12+
)
13+
14+
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
15+
16+
bazel_skylib_workspace()
317

418
git_repository(
519
name = "google_benchmark",

bazel/cJSON.BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ cc_library(
33
name = "cJSON",
44
srcs = ["cJSON.c"],
55
hdrs = ["cJSON.h"],
6-
copts = ['-O3' ,'-DNDEBUG', '-march=haswell'],
6+
copts = ['-O3' ,'-DNDEBUG',],
77
)
8+

bazel/yyjson.BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ cc_library(
44
srcs = ["src/yyjson.c"],
55
hdrs = ["src/yyjson.h"],
66
includes = ["src"],
7-
copts = ['-O3', '-DNDEBUG', '-march=haswell', '-g'],
7+
copts = ['-O3', '-DNDEBUG', '-g'],
88
)
9+

include/sonic/allocator.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,17 @@ class SpinLock {
8989
break;
9090
}
9191
while (lock_.load(std::memory_order_relaxed)) {
92+
// use pause or yield instruction will slow down lock acquisition
93+
// on contended locks.
94+
#ifndef SONIC_SPINLOCK_NO_PAUSE
95+
96+
#if defined(__x86_64__) || defined(_M_AMD64)
9297
__builtin_ia32_pause();
98+
#elif defined(__aarch64__) || defined(_M_ARM64)
99+
asm volatile("yield");
100+
#endif
101+
102+
#endif
93103
}
94104
}
95105
}

include/sonic/dom/dynamicnode.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
#include "sonic/dom/type.h"
2828
#include "sonic/error.h"
2929
#include "sonic/internal/ftoa.h"
30-
#include "sonic/internal/itoa.h"
31-
#include "sonic/internal/quote.h"
3230
#include "sonic/writebuffer.h"
3331

3432
namespace sonic_json {

include/sonic/dom/handler.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <string>
2020

2121
#include "sonic/dom/type.h"
22-
#include "sonic/internal/haswell.h"
22+
#include "sonic/internal/arch/simd_base.h"
2323
#include "sonic/string_view.h"
2424
#include "sonic/writebuffer.h"
2525

@@ -153,7 +153,7 @@ class SAXHandler {
153153
if (pairs) {
154154
void *mem = obj.template containerMalloc<MemberType>(pairs, *alloc_);
155155
obj.setChildren(mem);
156-
internal::haswell::xmemcpy<sizeof(MemberType)>(
156+
internal::Xmemcpy<sizeof(MemberType)>(
157157
(void *)obj.getObjChildrenFirstUnsafe(), (void *)(&obj + 1), pairs);
158158
} else {
159159
obj.setChildren(nullptr);
@@ -169,7 +169,7 @@ class SAXHandler {
169169
arr.setLength(count, kArray);
170170
if (count) {
171171
arr.setChildren(arr.template containerMalloc<NodeType>(count, *alloc_));
172-
internal::haswell::xmemcpy<sizeof(NodeType)>(
172+
internal::Xmemcpy<sizeof(NodeType)>(
173173
(void *)arr.getArrChildrenFirstUnsafe(), (void *)(&arr + 1), count);
174174
} else {
175175
arr.setChildren(nullptr);
@@ -239,7 +239,7 @@ class LazySAXHandler {
239239
arr.setLength(count, kArray);
240240
if (count) {
241241
arr.setChildren(arr.template containerMalloc<NodeType>(count, *alloc_));
242-
internal::haswell::xmemcpy<sizeof(NodeType)>(
242+
internal::Xmemcpy<sizeof(NodeType)>(
243243
(void *)arr.getArrChildrenFirstUnsafe(), (void *)(&arr + 1), count);
244244
stack_.Pop<NodeType>(count);
245245
} else {
@@ -254,7 +254,7 @@ class LazySAXHandler {
254254
if (pairs) {
255255
void *mem = obj.template containerMalloc<MemberType>(pairs, *alloc_);
256256
obj.setChildren(mem);
257-
internal::haswell::xmemcpy<sizeof(MemberType)>(
257+
internal::Xmemcpy<sizeof(MemberType)>(
258258
(void *)obj.getObjChildrenFirstUnsafe(), (void *)(&obj + 1), pairs);
259259
stack_.Pop<MemberType>(pairs);
260260
} else {

0 commit comments

Comments
 (0)