Skip to content

Commit 0e6ea76

Browse files
authored
Make checkperf work on Windows (simdjson#799)
* Make command line arguments work for Windows * Run checkperf on Windows
1 parent 0514588 commit 0e6ea76

19 files changed

+916
-235
lines changed

.appveyor.yml

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,34 @@
11
version: '{build}'
2-
branches:
3-
only:
4-
- master
5-
clone_folder: c:\projects\simdjson
6-
platform: x64
7-
image:
8-
- Visual Studio 2019
9-
- Visual Studio 2017
2+
branches: { only: [ master ] }
103
configuration: Release
4+
image: Visual Studio 2019
5+
platform: x64
6+
117
environment:
128
matrix:
13-
- SIMDJSON_BUILD_STATIC: ON
14-
SIMDJSON_ENABLE_THREADS: OFF
15-
SIMDJSON_PLATFORM: x64
16-
- SIMDJSON_BUILD_STATIC: ON
17-
SIMDJSON_ENABLE_THREADS: OFF
18-
SIMDJSON_PLATFORM: Win32
19-
- SIMDJSON_BUILD_STATIC: OFF
20-
SIMDJSON_ENABLE_THREADS: ON
21-
SIMDJSON_PLATFORM: x64
9+
- job_name: VS2019
10+
CMAKE_ARGS: -DSIMDJSON_CHECKPERF_BRANCH=jkeiser/parse-t
11+
- job_name: VS2017 (Static, No Threads)
12+
image: Visual Studio 2017
13+
CMAKE_ARGS: -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_ENABLE_THREADS=OFF
14+
CTEST_ARGS: -E checkperf
15+
- job_name: VS2019 (Win32)
16+
platform: Win32
17+
CMAKE_ARGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_ENABLE_THREADS=ON # This should be the default. Testing anyway.
18+
CTEST_ARGS: -E checkperf
2219

2320
build_script:
2421
- set
2522
- mkdir build
2623
- cd build
2724
- cmake --version
28-
- cmake -DSIMDJSON_BUILD_STATIC=%SIMDJSON_BUILD_STATIC% -DSIMDJSON_ENABLE_THREADS=%SIMDJSON_ENABLE_THREADS% -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_GENERATOR_PLATFORM=%SIMDJSON_PLATFORM% ..
25+
- cmake -A %Platform% %CMAKE_ARGS% --parallel ..
2926
- cmake -LH ..
3027
- cmake --build . --config %Configuration% --verbose --parallel
3128

3229
test_script:
33-
- ctest --output-on-failure -C %Configuration% --verbose --parallel
34-
30+
- ctest --output-on-failure -C %Configuration% --verbose %CTEST_ARGS% --parallel
31+
32+
clone_folder: c:\projects\simdjson
3533
matrix:
3634
fast_finish: true
37-
exclude:
38-
# Don't build all variants on 2017, just running it to make sure readme_tests succeed
39-
- image: Visual Studio 2017
40-
SIMDJSON_BUILD_STATIC: ON
41-
SIMDJSON_ENABLE_THREADS: OFF

benchmark/CMakeLists.txt

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
include_directories( . linux )
2-
link_libraries(simdjson simdjson-flags)
2+
link_libraries(simdjson simdjson-flags simdjson-windows-headers)
33
# add_executable(benchfeatures benchfeatures.cpp) # doesn't presently compile at all
44
add_executable(get_corpus_benchmark get_corpus_benchmark.cpp)
55
add_executable(perfdiff perfdiff.cpp)
@@ -35,15 +35,17 @@ if (SIMDJSON_COMPETITION)
3535
target_compile_definitions(allparsingcompetition PRIVATE ALLPARSER)
3636
endif()
3737

38-
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
39-
add_test(NAME checkperf
40-
COMMAND ${CMAKE_COMMAND} -E env
41-
CHECKPERF_REPOSITORY=https://github.com/simdjson/simdjson
42-
CHECKPERF_BRANCH=master
43-
CHECKPERF_DIR=${CMAKE_CURRENT_BINARY_DIR}/simdjson-master
44-
CHECKPERF_CMAKECACHE=${SIMDJSON_USER_CMAKECACHE}
45-
bash ${CMAKE_CURRENT_SOURCE_DIR}/checkperf.sh ${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json)
46-
set_property(TEST checkperf APPEND PROPERTY LABELS per_implementation)
47-
set_property(TEST checkperf APPEND PROPERTY DEPENDS parse perfdiff ${SIMDJSON_USER_CMAKECACHE})
48-
set_property(TEST checkperf PROPERTY RUN_SERIAL TRUE)
49-
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
38+
include(checkperf.cmake)
39+
40+
# IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
41+
# add_test(NAME checkperf
42+
# COMMAND ${CMAKE_COMMAND} -E env
43+
# CHECKPERF_REPOSITORY=${SIMDJSON_GITHUB_REPOSITORY}
44+
# CHECKPERF_BRANCH=master
45+
# CHECKPERF_DIR=${CMAKE_CURRENT_BINARY_DIR}/simdjson-master
46+
# CHECKPERF_CMAKECACHE=${SIMDJSON_USER_CMAKECACHE}
47+
# bash ${CMAKE_CURRENT_SOURCE_DIR}/checkperf.sh ${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json)
48+
# set_property(TEST checkperf APPEND PROPERTY LABELS per_implementation)
49+
# set_property(TEST checkperf APPEND PROPERTY DEPENDS parse perfdiff ${SIMDJSON_USER_CMAKECACHE})
50+
# set_property(TEST checkperf PROPERTY RUN_SERIAL TRUE)
51+
# ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")

benchmark/benchfeatures.cpp

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#include <cctype>
55
#ifndef _MSC_VER
66
#include <dirent.h>
7-
#include <unistd.h>
87
#endif
8+
#include <unistd.h>
99
#include <cinttypes>
1010
#include <initializer_list>
1111

@@ -84,42 +84,38 @@ struct option_struct {
8484
bool verbose = false;
8585

8686
option_struct(int argc, char **argv) {
87-
#ifndef _MSC_VER
88-
int c;
89-
90-
while ((c = getopt(argc, argv, "vtn:i:a:s:")) != -1) {
91-
switch (c) {
92-
case 'n':
93-
iterations = atoi(optarg);
94-
break;
95-
case 'i':
96-
iteration_step = atoi(optarg);
97-
break;
98-
case 'v':
99-
verbose = true;
100-
break;
101-
case 'a':
102-
arch = parse_architecture(optarg);
103-
if (arch == architecture::UNSUPPORTED) {
104-
exit_usage(string("Unsupported option value -a ") + optarg + ": expected -a HASWELL, WESTMERE or ARM64");
105-
}
106-
break;
107-
case 's':
108-
if (!strcmp(optarg, "stage1")) {
109-
stage1_only = true;
110-
} else if (!strcmp(optarg, "all")) {
111-
stage1_only = false;
112-
} else {
113-
exit_usage(string("Unsupported option value -s ") + optarg + ": expected -s stage1 or all");
114-
}
115-
break;
116-
default:
117-
exit_error("Unexpected argument " + c);
87+
int c;
88+
89+
while ((c = getopt(argc, argv, "vtn:i:a:s:")) != -1) {
90+
switch (c) {
91+
case 'n':
92+
iterations = atoi(optarg);
93+
break;
94+
case 'i':
95+
iteration_step = atoi(optarg);
96+
break;
97+
case 'v':
98+
verbose = true;
99+
break;
100+
case 'a':
101+
arch = parse_architecture(optarg);
102+
if (arch == architecture::UNSUPPORTED) {
103+
exit_usage(string("Unsupported option value -a ") + optarg + ": expected -a HASWELL, WESTMERE or ARM64");
118104
}
105+
break;
106+
case 's':
107+
if (!strcmp(optarg, "stage1")) {
108+
stage1_only = true;
109+
} else if (!strcmp(optarg, "all")) {
110+
stage1_only = false;
111+
} else {
112+
exit_usage(string("Unsupported option value -s ") + optarg + ": expected -s stage1 or all");
113+
}
114+
break;
115+
default:
116+
exit_error("Unexpected argument " + c);
119117
}
120-
#else
121-
int optind = 1;
122-
#endif
118+
}
123119

124120
// If architecture is not specified, pick the best supported architecture by default
125121
if (arch == architecture::UNSUPPORTED) {

benchmark/benchmarker.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#include <cctype>
88
#ifndef _MSC_VER
99
#include <dirent.h>
10-
#include <unistd.h>
1110
#endif
11+
#include <unistd.h>
1212
#include <cinttypes>
1313

1414
#include <cstdio>
@@ -45,6 +45,8 @@ using std::vector;
4545
using std::ostream;
4646
using std::ofstream;
4747
using std::exception;
48+
using std::min;
49+
using std::max;
4850

4951
// Initialize "verbose" to go nowhere. We'll read options in main() and set to cout if verbose is true.
5052
std::ofstream dev_null;
@@ -498,8 +500,8 @@ struct benchmarker {
498500
double freq1 = (stage1.best.cycles() / stage1.best.elapsed_sec()) / 1000000000.0;
499501
double freq2 = (stage2.best.cycles() / stage2.best.elapsed_sec()) / 1000000000.0;
500502
double freqall = (all_stages.best.cycles() / all_stages.best.elapsed_sec()) / 1000000000.0;
501-
double freqmin = std::min(freq1, freq2);
502-
double freqmax = std::max(freq1, freq2);
503+
double freqmin = min(freq1, freq2);
504+
double freqmax = max(freq1, freq2);
503505
if((freqall < 0.95 * freqmin) or (freqall > 1.05 * freqmax)) {
504506
printf("\nWarning: The processor frequency fluctuates in an expected way!!!\n"
505507
"Expect the overall speed not to match stage 1 and stage 2 speeds.\n"

benchmark/checkperf.cmake

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Relevant targets:
2+
# checkperf-parse: builds the reference checkperf-parse, syncing reference repository if needed
3+
# checkperf: builds the targets needed for checkperf (parse, perfdiff, checkperf-parse)
4+
# update-checkperf-repo: updates the reference repository we're checking performance against
5+
# checkperf-repo: initialize and sync reference repository (first time only)
6+
# TEST checkperf: runs the actual checkperf test
7+
8+
# Clone the repository if it's not there
9+
find_package(Git QUIET)
10+
if (Git_FOUND)
11+
# sync_git_repository(myrepo ...) creates two targets:
12+
# myrepo - if the repo does not exist, creates and syncs it against the origin branch
13+
# update_myrepo - will update the repo against the origin branch (and create if needed)
14+
function(sync_git_repository name dir remote branch url)
15+
# This conditionally creates the git repository
16+
add_custom_command(
17+
OUTPUT ${dir}/.git/config
18+
COMMAND ${GIT_EXECUTABLE} init ${dir}
19+
COMMAND ${GIT_EXECUTABLE} -C ${dir} remote add ${remote} ${url}
20+
)
21+
add_custom_target(init-${name} DEPENDS ${dir}/.git/config)
22+
# This conditionally syncs the git repository, first time only
23+
add_custom_command(
24+
OUTPUT ${dir}/.git/FETCH_HEAD
25+
COMMAND ${GIT_EXECUTABLE} remote set-url ${remote} ${url}
26+
COMMAND ${GIT_EXECUTABLE} fetch --depth=1 ${remote} ${branch}
27+
COMMAND ${GIT_EXECUTABLE} reset --hard ${remote}/${branch}
28+
WORKING_DIRECTORY ${dir}
29+
DEPENDS init-${name}
30+
)
31+
# This is the ${name} target, which will create and sync the repo first time only
32+
add_custom_target(${name} DEPENDS ${dir}/.git/FETCH_HEAD)
33+
# This is the update-${name} target, which will sync the repo (creating it if needed)
34+
add_custom_target(
35+
update-${name}
36+
COMMAND ${GIT_EXECUTABLE} remote set-url ${remote} ${url}
37+
COMMAND ${GIT_EXECUTABLE} fetch --depth=1 ${remote} ${branch}
38+
COMMAND ${GIT_EXECUTABLE} reset --hard ${remote}/${branch}
39+
WORKING_DIRECTORY ${dir}
40+
DEPENDS init-${name}
41+
)
42+
endfunction(sync_git_repository)
43+
44+
set(SIMDJSON_CHECKPERF_REMOTE origin CACHE STRING "Remote repository to compare performance against")
45+
set(SIMDJSON_CHECKPERF_BRANCH master CACHE STRING "Branch to compare performance against")
46+
set(SIMDJSON_CHECKPERF_DIR ${CMAKE_CURRENT_BINARY_DIR}/checkperf-reference/${SIMDJSON_CHECKPERF_BRANCH} CACHE STRING "Location to put checkperf performance comparison repository")
47+
set(SIMDJSON_CHECKPERF_ARGS ${EXAMPLE_JSON} CACHE STRING "Arguments to pass to parse during checkperf")
48+
sync_git_repository(checkperf-repo ${SIMDJSON_CHECKPERF_DIR} ${SIMDJSON_CHECKPERF_REMOTE} ${SIMDJSON_CHECKPERF_BRANCH} ${SIMDJSON_GITHUB_REPOSITORY})
49+
50+
# Commands to cause cmake on benchmark/checkperf-master/build/
51+
# - first, copy CMakeCache.txt
52+
add_custom_command(
53+
OUTPUT ${SIMDJSON_CHECKPERF_DIR}/build/CMakeCache.txt
54+
COMMAND ${CMAKE_COMMAND} -E make_directory ${SIMDJSON_CHECKPERF_DIR}/build
55+
COMMAND ${CMAKE_COMMAND} -E copy ${SIMDJSON_USER_CMAKECACHE} ${SIMDJSON_CHECKPERF_DIR}/build/CMakeCache.txt
56+
DEPENDS checkperf-repo simdjson-user-cmakecache
57+
)
58+
# - second, cmake ..
59+
add_custom_command(
60+
OUTPUT ${SIMDJSON_CHECKPERF_DIR}/build/cmake_install.cmake # We make many things but this seems the most cross-platform one we can depend on
61+
COMMAND ${CMAKE_COMMAND} -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_COMPETITION=OFF -G ${CMAKE_GENERATOR} ..
62+
WORKING_DIRECTORY ${SIMDJSON_CHECKPERF_DIR}/build
63+
DEPENDS ${SIMDJSON_CHECKPERF_DIR}/build/CMakeCache.txt
64+
)
65+
66+
# - third, build parse.
67+
if (CMAKE_CONFIGURATION_TYPES)
68+
set(CHECKPERF_PARSE ${SIMDJSON_CHECKPERF_DIR}/build/benchmark/$<CONFIGURATION>/parse)
69+
else()
70+
set(CHECKPERF_PARSE ${SIMDJSON_CHECKPERF_DIR}/build/benchmark/parse)
71+
endif()
72+
add_custom_target(
73+
checkperf-parse ALL # TODO is ALL necessary?
74+
# Build parse
75+
COMMAND ${CMAKE_COMMAND} --build . --target parse --config $<CONFIGURATION>
76+
WORKING_DIRECTORY ${SIMDJSON_CHECKPERF_DIR}/build
77+
DEPENDS ${SIMDJSON_CHECKPERF_DIR}/build/cmake_install.cmake # We make many things but this seems the most cross-platform one we can depend on
78+
)
79+
80+
# Target to build everything needed for the checkperf test
81+
add_custom_target(checkperf DEPENDS parse perfdiff checkperf-parse)
82+
83+
# Add the actual checkperf test
84+
add_test(
85+
NAME checkperf
86+
# COMMAND ECHO $<TARGET_FILE:perfdiff> \"$<TARGET_FILE:parse> -t ${SIMDJSON_CHECKPERF_ARGS}\" \"${CHECKPERF_PARSE} -t ${SIMDJSON_CHECKPERF_ARGS}\" }
87+
COMMAND $<TARGET_FILE:perfdiff> $<TARGET_FILE:parse> ${CHECKPERF_PARSE} -t ${SIMDJSON_CHECKPERF_ARGS}
88+
)
89+
set_property(TEST checkperf APPEND PROPERTY LABELS per_implementation)
90+
set_property(TEST checkperf APPEND PROPERTY DEPENDS parse perfdiff ${SIMDJSON_USER_CMAKECACHE})
91+
set_property(TEST checkperf PROPERTY RUN_SERIAL TRUE)
92+
93+
endif (Git_FOUND)

benchmark/checkperf.sh

Lines changed: 0 additions & 48 deletions
This file was deleted.

benchmark/event_counter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#include <cctype>
66
#ifndef _MSC_VER
77
#include <dirent.h>
8-
#include <unistd.h>
98
#endif
9+
#include <unistd.h>
1010
#include <cinttypes>
1111

1212
#include <cstdio>

0 commit comments

Comments
 (0)