Skip to content

Commit 151c225

Browse files
author
Todd L. Montgomery
committed
aeron-io#45: added C++ perf tests into perf/cpp and perf-build.xml
1 parent c54d627 commit 151c225

13 files changed

+1323
-1
lines changed

perf-build.xml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<property name="dir.target.perf.classes" location="target/perf/classes"/>
1111
<property name="dir.target.perf.java" location="target/perf/java"/>
1212
<property name="dir.target.perf.dist" location="target/perf/dist"/>
13+
<property name="dir.target.perf.cpp" location="target/perf/cpp"/>
1314

1415
<property file="build-local.properties"/>
1516

@@ -30,7 +31,7 @@
3031
</target>
3132

3233
<target name="clean">
33-
<deltree dir="target/perf"/>
34+
<delete dir="target/perf"/>
3435
</target>
3536

3637
<target name="java:codegen" depends="init">
@@ -91,4 +92,35 @@
9192
</exec>
9293
</target>
9394

95+
<target name="cpp:codegen" depends="init">
96+
<java classname="uk.co.real_logic.sbe.SbeTool">
97+
<classpath refid="perf.tools.classpath"/>
98+
<sysproperty key="sbe.output.dir" value="${dir.target.perf.cpp}"/>
99+
<sysproperty key="sbe.target.language" value="Cpp98"/>
100+
<arg value="${dir.resources.sbe}/car-c.xml"/>
101+
</java>
102+
<java classname="uk.co.real_logic.sbe.SbeTool">
103+
<classpath refid="perf.tools.classpath"/>
104+
<sysproperty key="sbe.output.dir" value="${dir.target.perf.cpp}"/>
105+
<sysproperty key="sbe.target.language" value="Cpp98"/>
106+
<arg value="${dir.resources.sbe}/fix-message-samples.xml"/>
107+
</java>
108+
</target>
109+
110+
<target name="cpp:compile" depends="clean, init, cpp:codegen">
111+
<sequential>
112+
<exec executable="cmake" dir="target/perf">
113+
<arg value="../../perf/cpp"/>
114+
</exec>
115+
<exec executable="make" dir="target/perf"/>
116+
</sequential>
117+
</target>
118+
119+
<target name="cpp:perf:test" depends="cpp:compile">
120+
<sequential>
121+
<exec executable="target/perf/benchlet-sbe-md-runner"/>
122+
<exec executable="target/perf/benchlet-sbe-car-runner"/>
123+
</sequential>
124+
</target>
125+
94126
</project>

perf/cpp/CMakeLists.txt

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#
2+
# Copyright 2013 Real Logic Ltd.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
cmake_minimum_required(VERSION 2.8)
17+
18+
option(USE_PROTOBUF "Build Protobuf installed in PROTOBUF_HOME." OFF)
19+
option(RETRIEVE_AND_BUILD_PROTOBUF "Retrieve and build protobuf in PROTOBUF_HOME. Not Windows!!" OFF)
20+
21+
if(UNIX)
22+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Ofast")
23+
endif()
24+
25+
if(APPLE)
26+
add_definitions(-DDarwin)
27+
elseif(WIN32)
28+
add_definitions(-DWIN32)
29+
else()
30+
add_definitions(-D_GNU_SOURCE)
31+
endif()
32+
33+
include_directories(
34+
# the generated code directory
35+
${CMAKE_CURRENT_BINARY_DIR}/cpp
36+
# the benchmark code directory
37+
${CMAKE_CURRENT_SOURCE_DIR}/../../main/cpp
38+
)
39+
40+
set(SRCS_BENCHLET_MAIN
41+
benchlet-main.cpp
42+
)
43+
44+
set(SBE_CAR_SCHEMA ${CMAKE_CURRENT_SOURCE_DIR}/../resources/sbe/car-c.xml)
45+
set(SBE_MD_SCHEMA ${CMAKE_CURRENT_SOURCE_DIR}/../resources/sbe/fix-message-samples.xml)
46+
set(SBE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR}/cpp)
47+
set(SBE_JAR ${CMAKE_CURRENT_BINARY_DIR}/../dist/sbe.jar)
48+
set(SBE_MD_GENERATED_HEADERS
49+
${SBE_TARGET_DIR}/uk_co_real_logic_sbe_samples_fix/MarketDataIncrementalRefreshTrades.hpp
50+
${SBE_TARGET_DIR}/uk_co_real_logic_sbe_samples_fix/MessageHeader.hpp
51+
)
52+
set(SBE_CAR_GENERATED_HEADERS
53+
${SBE_TARGET_DIR}/uk_co_real_logic_sbe_examples_car/Car.hpp
54+
${SBE_TARGET_DIR}/uk_co_real_logic_sbe_examples_car/MessageHeader.hpp
55+
)
56+
57+
#
58+
# Generation of the C++ codecs are done here as well as in the ant build as this might be used standalone
59+
#
60+
61+
find_package(Java)
62+
63+
add_custom_command(
64+
OUTPUT ${SBE_MD_GENERATED_HEADERS}
65+
DEPENDS ${SBE_MD_SCHEMA}
66+
COMMAND ${Java_JAVA_EXECUTABLE} -Dsbe.output.dir=${SBE_TARGET_DIR} -Dsbe.target.language="cpp98" -jar ${SBE_JAR} ${SBE_MD_SCHEMA}
67+
)
68+
add_custom_target(generate_sbe_md DEPENDS ${SBE_MD_GENERATED_HEADERS})
69+
70+
add_custom_command(
71+
OUTPUT ${SBE_CAR_GENERATED_HEADERS}
72+
DEPENDS ${SBE_CAR_SCHEMA}
73+
COMMAND ${Java_JAVA_EXECUTABLE} -Dsbe.output.dir=${SBE_TARGET_DIR} -Dsbe.target.language="cpp98" -jar ${SBE_JAR} ${SBE_CAR_SCHEMA}
74+
)
75+
add_custom_target(generate_sbe_car DEPENDS ${SBE_CAR_GENERATED_HEADERS})
76+
77+
add_executable(benchlet-sbe-car-runner ${SRCS_BENCHLET_MAIN} CarBench.cpp)
78+
add_executable(benchlet-sbe-md-runner ${SRCS_BENCHLET_MAIN} MarketDataBench.cpp)
79+
add_dependencies(benchlet-sbe-md-runner generate_sbe_md)
80+
add_dependencies(benchlet-sbe-car-runner generate_sbe_car)
81+
82+
set(DEV_DIR $ENV{HOME}/dev CACHE PATH "Path to dependencies")
83+
84+
set(PROTOBUF_VSN "protobuf-2.5.0")
85+
set(PROTOBUF_HOME ${DEV_DIR}/${PROTOBUF_VSN} CACHE PATH "Path to protobuf install directory")
86+
set(PROTOBUF_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen/cpp)
87+
88+
if(RETRIEVE_AND_BUILD_PROTOBUF)
89+
if(EXISTS ${PROTOBUF_HOME})
90+
message("PROTUBUF_HOME exists.")
91+
else()
92+
file(MAKE_DIRECTORY ${DEV_DIR}/deps)
93+
file(DOWNLOAD https://protobuf.googlecode.com/files/${PROTOBUF_VSN}.tar.gz ${DEV_DIR}/deps/${PROTOBUF_VSN}.tar.gz)
94+
execute_process(
95+
WORKING_DIRECTORY ${DEV_DIR}/deps
96+
COMMAND tar xzf ${DEV_DIR}/deps/${PROTOBUF_VSN}.tar.gz
97+
)
98+
execute_process(
99+
WORKING_DIRECTORY ${DEV_DIR}/deps/${PROTOBUF_VSN}
100+
OUTPUT_FILE ${DEV_DIR}/deps/${PROTOBUF_VSN}.configure.out
101+
ERROR_FILE ${DEV_DIR}/deps/${PROTOBUF_VSN}.configure.err
102+
COMMAND ./configure --prefix=${PROTOBUF_HOME}
103+
)
104+
execute_process(
105+
WORKING_DIRECTORY ${DEV_DIR}/deps/${PROTOBUF_VSN}
106+
OUTPUT_FILE ${DEV_DIR}/deps/${PROTOBUF_VSN}.make.out
107+
ERROR_FILE ${DEV_DIR}/deps/${PROTOBUF_VSN}.make.err
108+
COMMAND make
109+
)
110+
execute_process(
111+
WORKING_DIRECTORY ${DEV_DIR}/deps/${PROTOBUF_VSN}
112+
OUTPUT_FILE ${DEV_DIR}/deps/${PROTOBUF_VSN}.make-install.out
113+
ERROR_FILE ${DEV_DIR}/deps/${PROTOBUF_VSN}.make-install.err
114+
COMMAND make install
115+
)
116+
endif()
117+
endif()
118+
119+
if(USE_PROTOBUF)
120+
set(PROTOBUF_CAR_SCHEMA ${CMAKE_CURRENT_SOURCE_DIR}/../resources/protobuf/car.proto)
121+
set(PROTOBUF_MD_SCHEMA ${CMAKE_CURRENT_SOURCE_DIR}/../resources/protobuf/fix-messages.proto)
122+
set(PROTOBUF_MD_GENERATED_HEADERS
123+
${CMAKE_CURRENT_BINARY_DIR}/cpp/fix-messages.pb.h
124+
)
125+
set(PROTOBUF_MD_GENERATED_SOURCES
126+
${CMAKE_CURRENT_BINARY_DIR}/cpp/fix-messages.pb.cc
127+
)
128+
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpp)
129+
add_custom_command(
130+
OUTPUT ${PROTOBUF_MD_GENERATED_HEADERS} ${PROTOBUF_MD_GENERATED_SOURCES}
131+
DEPENDS ${PROTOBUF_MD_SCHEMA}
132+
COMMAND ${PROTOBUF_HOME}/bin/protoc -I${CMAKE_CURRENT_SOURCE_DIR}/../resources/protobuf --cpp_out ${PROTOBUF_TARGET_DIR} ${PROTOBUF_MD_SCHEMA}
133+
)
134+
include_directories(AFTER ${PROTOBUF_HOME}/include)
135+
find_library(PROTOBUF_LIBS protobuf ${PROTOBUF_HOME}/lib)
136+
add_custom_target(generate_protobuf_md DEPENDS ${PROTOBUF_MD_GENERATED_HEADERS} ${PROTOBUF_MD_GENERATED_SOURCES})
137+
add_executable(benchlet-pb-md-runner ${SRCS_BENCHLET_MAIN} ${PROTOBUF_MD_GENERATED_SOURCES} PbMarketDataBench.cpp)
138+
add_dependencies(benchlet-pb-md-runner generate_protobuf_md)
139+
target_link_libraries(benchlet-pb-md-runner ${PROTOBUF_LIBS})
140+
endif()

perf/cpp/CarBench.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2013 Real Logic Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "benchlet.hpp"
17+
#include "SbeCarCodecBench.hpp"
18+
19+
#define MAX_CAR_BUFFER (1000*1000)
20+
#define MAX_N 10
21+
22+
class SbeCarBench : public Benchmark
23+
{
24+
public:
25+
virtual void setUp(void)
26+
{
27+
buffer_ = new char[MAX_CAR_BUFFER];
28+
bench_.runEncode(buffer_, MAX_N); // set buffer up for decoding runs
29+
std::cout << "MAX N = " << MAX_N << " [for Multiple runs]" << std::endl;
30+
};
31+
32+
virtual void tearDown(void)
33+
{
34+
delete[] buffer_;
35+
};
36+
37+
SbeCarCodecBench bench_;
38+
char *buffer_;
39+
};
40+
41+
static struct Benchmark::Config cfg[] = {
42+
{ Benchmark::ITERATIONS, "1000000" },
43+
{ Benchmark::BATCHES, "20" }
44+
};
45+
46+
BENCHMARK_CONFIG(SbeCarBench, RunSingleEncode, cfg)
47+
{
48+
bench_.runEncode(buffer_);
49+
}
50+
51+
BENCHMARK_CONFIG(SbeCarBench, RunSingleDecode, cfg)
52+
{
53+
bench_.runDecode(buffer_);
54+
}
55+
56+
BENCHMARK_CONFIG(SbeCarBench, RunSingleEncodeAndDecode, cfg)
57+
{
58+
bench_.runEncodeAndDecode(buffer_);
59+
}
60+
61+
static struct Benchmark::Config cfgMulti[] = {
62+
{ Benchmark::ITERATIONS, "100000" },
63+
{ Benchmark::BATCHES, "20" }
64+
};
65+
66+
BENCHMARK_CONFIG(SbeCarBench, RunMultipleEncode, cfgMulti)
67+
{
68+
bench_.runEncode(buffer_, MAX_N);
69+
}
70+
71+
BENCHMARK_CONFIG(SbeCarBench, RunMultipleDecode, cfgMulti)
72+
{
73+
bench_.runDecode(buffer_, MAX_N);
74+
}
75+
76+
BENCHMARK_CONFIG(SbeCarBench, RunMultipleEncodeAndDecode, cfgMulti)
77+
{
78+
bench_.runEncodeAndDecode(buffer_, MAX_N);
79+
}

perf/cpp/CodecBench.hpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2013 Real Logic Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#ifndef _CODEC_BENCH_HPP
17+
#define _CODEC_BENCH_HPP
18+
19+
// Interface for encoding and decoding and also benchmark harness
20+
template <typename Derived>
21+
class CodecBench
22+
{
23+
public:
24+
int encode_buffer(char *buffer)
25+
{
26+
return static_cast<Derived *>(this)->encode(buffer);
27+
};
28+
29+
int decode_buffer(const char *buffer)
30+
{
31+
return static_cast<Derived *>(this)->decode(buffer);
32+
};
33+
34+
/*
35+
* Benchmarks
36+
*/
37+
38+
/*
39+
* Run 1 encoding
40+
*/
41+
void runEncode(char *buffer)
42+
{
43+
encode_buffer(buffer);
44+
};
45+
46+
/*
47+
* Run 1 decoding
48+
*/
49+
void runDecode(const char *buffer)
50+
{
51+
decode_buffer(buffer);
52+
};
53+
54+
/*
55+
* Run 1 encoding + decoding
56+
*/
57+
void runEncodeAndDecode(char *buffer)
58+
{
59+
encode_buffer(buffer);
60+
decode_buffer(buffer);
61+
};
62+
63+
/*
64+
* Run n encodings
65+
*/
66+
void runEncode(char *buffer, const int n)
67+
{
68+
char *ptr = buffer;
69+
70+
for (int i = 0; i < n; i++)
71+
{
72+
ptr += encode_buffer(ptr);
73+
}
74+
};
75+
76+
/*
77+
* Run n decodings
78+
*/
79+
void runDecode(const char *buffer, const int n)
80+
{
81+
const char *ptr = buffer;
82+
83+
for (int i = 0; i < n; i++)
84+
{
85+
ptr += decode_buffer(ptr);
86+
}
87+
};
88+
89+
/*
90+
* Run n encodings followed by n decodings
91+
*/
92+
void runEncodeAndDecode(char *buffer, const int n)
93+
{
94+
char *ptr = buffer;
95+
96+
for (int i = 0; i < n; i++)
97+
{
98+
ptr += encode_buffer(ptr);
99+
}
100+
ptr = buffer;
101+
for (int i = 0; i < n; i++)
102+
{
103+
ptr += decode_buffer(ptr);
104+
}
105+
};
106+
};
107+
108+
#endif /* _CODEC_BENCH_HPP */

0 commit comments

Comments
 (0)