This sample shows how to measure latency and use the warm-up feature.
#include "../PerformanceCounter.h"
#include "../SessionTimeMarks.h"
{
public:
explicit MySessionListener(size_t numberOfMessages)
: marks_(new
OnixS::Sample::SessionTimeMarks[numberOfMessages])
, active_(false)
, counter_(0)
, numberOfMessages_(numberOfMessages) {
std::memset(marks_, 0, sizeof(OnixS::Sample::SessionTimeMarks) * numberOfMessages_);
}
~MySessionListener() ONIXS_FIXENGINE_OVERRIDE {
delete[] marks_;
}
return;
OnixS::Sample::PerformanceCounter::current(&marks_[counter_].recvFinish);
++counter_;
ready_.release();
}
void onReceivedBytes(const char * , size_t ,
return;
OnixS::Sample::PerformanceCounter::current(&marks_[counter_].recvStart);
}
return;
OnixS::Sample::PerformanceCounter::current(&marks_[counter_].sendFinish);
}
active_ = value;
}
return marks_[counter_];
}
counter_ = 0;
std::memset(marks_, 0, sizeof(OnixS::Sample::SessionTimeMarks) * numberOfMessages_);
}
void spinWaitReceivedMsg() {
while(!ready_.tryAcquire())
}
OnixS::Sample::SessionTimeMarks * marks_;
private:
bool active_;
size_t counter_;
const size_t numberOfMessages_;
};
#include "Listener.h"
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
using namespace OnixS::Sample;
namespace {
void getSessionTimeMarksStatistics(
MySessionListener & listener,
unsigned int numberOfMessages,
unsigned int sendPeriodUsec,
unsigned int warmupPeriodUsec)
{
listener.ready_.acquire();
listener.clear();
listener.ready_.release();
assert(valueRef);
const FlatFieldKey valueKey = order.
allocateKey(valueRef);
for(unsigned int i = 0; i < numberOfMessages; ++i) {
order.
set(valueKey, i + 1);
listener.spinWaitReceivedMsg();
OnixS::Sample::SessionTimeMarks & currentMark = listener.currentMark();
PerformanceCounter::current(¤tMark.sendStart);
PerformanceCounter::current(¤tMark.overallSendFinish);
if(warmupPeriodUsec) {
const PerformanceCounter::Count start = PerformanceCounter::current();
do {
}
while(PerformanceCounter::elapsedMicroseconds(start) < sendPeriodUsec);
}
else if(sendPeriodUsec)
}
}
}
int main(int argc, char * argv[])
{
clog << "OnixS Latency Benchmark Sample." << endl;
clog << "Advance usage: Latency.exe numberOfMessages sendPeriodUsec warmupPeriodUsec" << endl;
#if _DEBUG
cerr << "Please use RELEASE build to measure latency." << endl;
return 1;
#endif
#ifdef _DEBUG
const unsigned int NumberOfMessages = (argc > 1 ? std::atoi(argv[1]) : 1000);
#else
const unsigned int NumberOfMessages = (argc > 1 ? std::atoi(argv[1]) : 10000);
#endif
const unsigned int SendPeriodUsec = (argc > 2 ? (std::atoi(argv[2])) : 100);
const unsigned int WarmupPeriodUsec = (argc > 3 ? std::atoi(argv[3]) : 100);
clog << "Current parameters: numberOfMessages=" << NumberOfMessages << "; SendPeriodUsec=" <<
SendPeriodUsec << "; warmupPeriodUsec=" << WarmupPeriodUsec << endl << endl;
try {
.validateRequiredFields(false)
.validateUnknownFields(false)
.validateUnknownMessages(false)
.receiveSpinningTimeout(10000)
.logBeforeSending(false)
.useSpinLock(true);
Engine::init(settings);
const Dictionary dictionary(
"LowLatencyDictionaryId");
const string rawMessage =
"8=FIX.4.2\0019=3\00135=D\00149=OnixS\00156=CME\00134=01\00152=20120709-10:10:54\00111=90001008\00121=1\00155=ABC\00154=1\00138=100\00140=1\00160=20120709-10:10:54\00110=000\001";
Message::parse(rawMessage.data(), rawMessage.size(), msg);
MySessionListener listener(NumberOfMessages);
Session acceptor(TargetCompId, SenderCompId, dictionary, &listener,
SessionStorageType::MemoryBased);
acceptor.sendingThreadAffinity(OtherThreadAffinity)
.receivingThreadAffinity(ReceivingThreadAffinity)
.logonAsAcceptor();
Session initiator(SenderCompId, TargetCompId, dictionary, &listener,
SessionStorageType::MemoryBased);
.receivingThreadAffinity(OtherThreadAffinity)
.logonAsInitiator("localhost", ListenPort, 0);
listener.active(true);
const unsigned int NumberOfWarmupMessages = NumberOfMessages > 1000 ? 1000 : NumberOfMessages;
getSessionTimeMarksStatistics(initiator, order, listener, NumberOfWarmupMessages,
SendPeriodUsec, WarmupPeriodUsec);
getSessionTimeMarksStatistics(initiator, order, listener, NumberOfMessages, SendPeriodUsec,
WarmupPeriodUsec);
listener.ready_.acquire();
listener.active(false);
acceptor.logout();
SessionTimeMarks::reportStatistics("Latency", listener.marks_, NumberOfMessages, false);
Engine::shutdown();
}
catch(const std::exception & ex) {
processSampleException(ex.what());
}
return 0;
}