OnixS C++ ICE Binary Order Entry Handler 1.2.3
API Documentation
Loading...
Searching...
No Matches
TCPDirectBenchmark.cpp
Go to the documentation of this file.
1/*
2 * Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3 *
4 * This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5 * and international copyright treaties.
6 *
7 * Access to and use of the software is governed by the terms of the applicable ONIXS Software
8 * Services Agreement (the Agreement) and Customer end user license agreements granting
9 * a non-assignable, non-transferable and non-exclusive license to use the software
10 * for it's own data processing purposes under the terms defined in the Agreement.
11 *
12 * Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13 * of this source code or associated reference material to any other location for further reproduction
14 * or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15 *
16 * Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17 * the terms of the Agreement is a violation of copyright law.
18 */
19// Uncomment to disable using of huge pages.
20//#define ONIXS_USE_HUGE_PAGE 0
21
22// Uncomment to enable debug mode.
23//#define ONIXS_DEBUGGING
24
26
27using namespace ONIXS_ICEBOE_NAMESPACE;
29
30#include <Settings/Defaults.h>
31#include <Common/Helpers.h>
32#include <Common/Listener.h>
33#include <Common/Settings.h>
34#include <Common/Signal.h>
35#include <Common/Tools.h>
36#include <Common/Emulator.h>
38
39#include <algorithm>
40
41using namespace Samples;
42
43
44int main(int argc, char* argv[])
45{
46 // `--help` to show options.
47 const AppConfiguration<
55 > cfg{"TCPDirectBenchmark", argc, argv};
56
57 int result = 0;
58 try
59 {
60 const auto numberOfMessages = cfg.numberOfMessages();
61 const auto warmupInterval = cfg.warmupInterval();
62 const auto intervalBetweenSending = (std::max)(cfg.intervalBetweenSending(), warmupInterval);
63 const auto storageType = cfg.storage();
64
65 ThisThread::affinity(cfg.mainThreadCpu());
67
68 auto settings = fillSettings(cfg);
69 const auto emulator = createEmulator(settings, cfg, true);
70
71 // Request Binary Order Gateway credentials from Binary Utility Service Gateway.
72 const auto bgwCredentials = receiveBgwCredentials(settings, cfg.host(), cfg.port());
73
74 settings
75 .receiveSpinningTimeout(1000 * 1000)
76 .useSpinLock(true)
77 .logBeforeSending(false)
78 .threadingModel(ThreadingModel::External);
79
80 printBenchmarkSettings(std::clog, numberOfMessages, intervalBetweenSending, warmupInterval, storageType);
81
82 const auto guard = setPriorityAndPolicy();
83
84 TcpDirectAttr attr;
85
86 // The default interface name could be provided by the environment variable
87 // ZF_ATTR="interface=<interface-name>", see TCPDirect specs.
88 attr.set("interface", cfg.nif());
89
90 TcpDirectStack stack{attr};
91
92 ReactorBenchmarkListener listener{numberOfMessages};
93 listener.measureOverhead();
94
95 try
96 {
97 const auto bgwSession = makeUnique<BgwSession>(stack, settings, &listener, cfg.storage());
98
99 const auto connected = bgwSession->connectAsync(bgwCredentials);
100
101 while(!connected.is_ready())
102 stack.dispatchEvents();
103
104 if(connected.has_exception())
105 connected.get();
106
107 auto order = Helper::createOrder(cfg.traderId());
108
109 std::clog << "\nWarm-up phase to make first calls faster..." << std::endl;
110
112 stack, *bgwSession, order, numberOfMessages, intervalBetweenSending, warmupInterval);
113
114 if(listener.receivedAllMessages())
115 {
116 std::clog << "\nMeasurement phase..." << std::endl;
117
119 stack, *bgwSession, order, numberOfMessages, intervalBetweenSending, warmupInterval);
120 }
121
122 const auto disconnected = bgwSession->disconnectAsync();
123
124 while(!disconnected.is_ready())
125 stack.dispatchEvents();
126
127 if(disconnected.has_exception())
128 disconnected.get();
129 }
130 catch(const std::exception& ex)
131 {
132 std::cerr << "\nEXCEPTION: " << ex.what() << std::endl;
133 result = 1;
134 }
135
136 while(!stack.isQuiescent())
137 stack.dispatchEvents();
138
139 if(listener.receivedAllMessages())
140 {
141 if(listener.packetGroupingDetected())
142 std::clog << "Attention: packet grouping detected! Increase the interval between sending!" << std::endl;
143
144 BenchmarkData::reportResults("Latency", listener.sendMarks(), listener.receiveMarks(), numberOfMessages, listener.overhead());
145 }
146 }
147 catch (const std::exception& ex)
148 {
149 std::cerr << "\nEXCEPTION: " << ex.what() << std::endl;
150 result = 1;
151 }
152
153 return result;
154}
155
#define ONIXS_ICEBOE_NAMESPACE
Definition ABI.h:113
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE
Definition ABI.h:114
int main(int argc, char *argv[])
const BenchmarkData::SendMarks * sendMarks() const noexcept
const BenchmarkData::ReceiveMarks * receiveMarks() const noexcept
const BenchmarkData::Overhead & overhead() const noexcept
bool packetGroupingDetected() const noexcept
TCPDirect Attributes to pass configuration details (a wrapper around the zf_attr struct).
void set(const std::string &name, const std::string &value)
Sets the attribute to the given value.
A high-level wrapper over the TCPDirect network stack.
bool isQuiescent() const noexcept override
void dispatchEvents() noexcept override
This function processes events on a stack and performs the necessary handling.
static void affinity(const CpuIndexes &cpuIndexes)
Sets the processor affinity mask for the current thread. The thread is rescheduled after this call.
bool receivedAllMessages() const noexcept
void collectSessionTimeMarks(Stack &stack, Session &session, MessageHolder< NewOrderRequest > &order, size_t numberOfMessages, size_t sendPeriod, size_t warmupPeriod)
static MessageHolder< NewOrderRequest > createOrder(const std::string &traderId)
Definition Helpers.h:104
std::shared_ptr< void > setPriorityAndPolicy(Session *session=nullptr)
Definition Helpers.h:150
std::pair< std::unique_ptr< GatewayEmulatorThread< BusSessionGatewayListener > >, std::unique_ptr< GatewayEmulatorThread< GatewayListener > > > createEmulator(const SessionSettings &settings, const ConnectivityConfiguration &cfg, bool tcpDirect=false)
Definition Emulator.h:159
BgwCredentials receiveBgwCredentials(SessionSettings settings, std::string host, Port port)
Definition Listener.h:265
SessionSettings fillSettings(const LogonConfiguration &logonCfg, const ConnectivityConfiguration &connCfg, const SettingsConfiguration &settingsCfg)
Definition Settings.h:32
void printBenchmarkSettings(std::ostream &o, size_t numberOfMessages, size_t intervalBetweenSending, size_t warmupInterval, SessionStorageType::Enum storageType)
Definition Helpers.h:182
std::unique_ptr< T > makeUnique(Args &&...args)
Definition Tools.h:30
static void reportResults(const std::string &name, const SendMarks *sendMarksArray, const ReceiveMarks *receiveMarksArray, std::size_t count, const Overhead &overhead)
@ External
Session events are handled by rolling an event loop in a user thread.
static void manageSignals() noexcept
Definition Signal.h:46