Skip to content

Instantly share code, notes, and snippets.

@thomasives
Last active April 5, 2023 14:50
Show Gist options
  • Save thomasives/1df7f1c668a465e8201819434e5b5112 to your computer and use it in GitHub Desktop.
Save thomasives/1df7f1c668a465e8201819434e5b5112 to your computer and use it in GitHub Desktop.
pvxs timing programs
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <time.h>
#include <float.h>
#include <pvxs/client.h>
#include <pvxs/log.h>
double monitorCreateRate(int channelCount)
{
using namespace pvxs;
using namespace pvxs::client;
auto ctxt(client::Context::fromEnv());
MPMCFIFO<std::shared_ptr<Subscription>> workqueue(channelCount);
std::vector<std::shared_ptr<Subscription>> subs;
struct timespec start;
clock_gettime(CLOCK_MONOTONIC, &start);
for (int index = 0; index < channelCount; index++){
std::stringstream ss;
ss << "TEST:CALC" << std::setw(5) << std::setfill('0') << index;
auto sub = ctxt.monitor(ss.str())
.event([&workqueue](Subscription& sub) {
// Subscription queue becomes not empty.
// Avoid I/O on PVXS worker thread,
// delegate to application thread
workqueue.push(sub.shared_from_this());
})
.exec();
subs.push_back(sub);
}
struct timespec end;
clock_gettime(CLOCK_MONOTONIC, &end);
double delta = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) * 1e-9;
return channelCount / delta;
}
int main(int argc,char *argv[])
{
using namespace pvxs;
using namespace pvxs::client;
// (Optional) configuring logging using $PVXS_LOG
logger_config_env();
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " CHANNEL_COUNT\n";
return 1;
}
int channelCount = std::atoi(argv[1]);
double max = 0;
double min = DBL_MAX;
double sum = 0;
double sumsq = 0;
int count = 500;
for (int i = 0; i < count; ++i) {
std::cout << i << "\n";
double rate = monitorCreateRate(channelCount);
if (rate > max) max = rate;
if (rate < min) min = rate;
sum += rate;
sumsq += rate * rate;
struct timespec sleep = { 0, 100000000 }; // 100 ms
nanosleep(&sleep, nullptr);
}
double avg = sum / count;
double stddev = sqrt((sumsq - avg * avg * count) / (count - 1));
double err = stddev / sqrt(count);
std::cout << "Channel create rate = " << avg << " +/- "
<< err << " (" << min << ", " << max << ") channels per second\n";
return(0);
}
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <pvxs/client.h>
#include <pvxs/log.h>
#include <time.h>
#include <float.h>
#include <math.h>
double timeMonitorLatency()
{
using namespace pvxs;
using namespace pvxs::client;
auto ctxt(client::Context::fromEnv());
MPMCFIFO<std::shared_ptr<Subscription>> workqueue(1000u);
std::vector<std::shared_ptr<Subscription>> subs;
std::stringstream ss;
ss << "TEST:CALC" << std::setw(5) << std::setfill('0') << 0;
struct timespec start;
clock_gettime(CLOCK_MONOTONIC, &start);
{
auto sub = ctxt.monitor(ss.str())
.event([&workqueue](Subscription& sub) {
// Subscription queue becomes not empty.
// Avoid I/O on PVXS worker thread,
// delegate to application thread
workqueue.push(sub.shared_from_this());
})
.exec();
subs.push_back(sub);
}
{
auto sub = workqueue.pop();
try {
Value update = sub->pop();
} catch(std::exception& e) {
std::cerr<<"Error "<<e.what()<<"\n";
}
}
struct timespec end;
clock_gettime(CLOCK_MONOTONIC, &end);
double delta = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) * 1e-9;
return delta;
}
int main(int argc,char *argv[])
{
using namespace pvxs;
using namespace pvxs::client;
// (Optional) configuring logging using $PVXS_LOG
logger_config_env();
double max = 0;
double min = DBL_MAX;
double sum = 0;
double sumsq = 0;
int count = 500;
for (int i = 0; i < count; ++i) {
std::cout << i << "\n";
double latency = timeMonitorLatency();
if (latency > max) max = latency;
if (latency < min) min = latency;
sum += latency;
sumsq += latency * latency;
struct timespec sleep = { 0, 100000000 }; // 100 ms
nanosleep(&sleep, nullptr);
}
double avg = sum / count;
double stddev = sqrt((sumsq - avg * avg * count) / (count - 1));
double err = stddev / sqrt(count);
std::cout << "Monitor latency = " << avg * 1000 << " +/- "
<< err * 1000 << " (" << min * 1000 << ", " << max * 1000 << ") ms\n";
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment