Performance Tuning
| Field | Value |
|---|---|
| Difficulty | Advanced |
| Estimated Read Time | 15-20 minutes |
| Labels | performance, tuning, async, queues |
Concept
This tutorial explains the first performance knobs most teams tune in async pipelines: queue depth, overflow policy, and metrics.
Why this comes late in the tutorial sequence: performance tuning only helps when your correctness baseline is already stable. This chapter assumes you can already run async push/pull and now want controlled throughput/latency tradeoffs.
What this chapter demonstrates:
- Running async mode with configurable queue depth.
- Comparing overflow strategies (
Block,KeepLatest,DropIncoming). - Reading runtime metrics (
inputs_enqueued, drops, latency, push cost, renegotiations).
Use-case guidance:
- Throughput bottlenecks: increase queue depth and inspect drop/latency behavior.
- Low-latency preference: favor latest-frame behavior in bursty streams.
- Backpressure-sensitive ingestion: prefer block policy for strict loss control.
Reference:
Learning Process
- Build an async run path with explicit queue and overflow settings.
- Push a deterministic workload and drain outputs to completion.
- Inspect metrics and input stats for latency/drop behavior.
- Validate tuning run completion with
CHECK,SIGNATURE, and[OK].
Run
NEAT_EXTRAS_ROOT=<sima-neat-*-Linux-extras>
cd $NEAT_EXTRAS_ROOT/lib/sima-neat/tutorials
./tutorial_v2_017_performance_tuning
Code
tutorials/017_performance_tuning/performance_tuning.cpp
// Tune async Session throughput via RunOptions: queue_depth, overflow_policy, metrics.
//
// Usage:
// tutorial_v2_017_performance_tuning [--iters 32] [--queue 4] [--drop block|latest|incoming]
#include "neat.h"
#include <opencv2/core.hpp>
#include <iostream>
#include <stdexcept>
#include <string>
namespace {
bool get_arg(int argc, char** argv, const std::string& key, std::string& out) {
for (int i = 1; i + 1 < argc; ++i) {
if (key == argv[i]) {
out = argv[i + 1];
return true;
}
}
return false;
}
int parse_int_arg(int argc, char** argv, const std::string& key, int def) {
std::string value;
if (!get_arg(argc, argv, key, value))
return def;
return std::stoi(value);
}
simaai::neat::OverflowPolicy parse_drop_policy(int argc, char** argv) {
std::string mode;
if (!get_arg(argc, argv, "--drop", mode))
return simaai::neat::OverflowPolicy::Block;
if (mode == "latest")
return simaai::neat::OverflowPolicy::KeepLatest;
if (mode == "incoming")
return simaai::neat::OverflowPolicy::DropIncoming;
return simaai::neat::OverflowPolicy::Block;
}
} // namespace
int main(int argc, char** argv) {
try {
const int iters = parse_int_arg(argc, argv, "--iters", 32);
const int queue_depth = parse_int_arg(argc, argv, "--queue", 4);
cv::Mat rgb(120, 160, CV_8UC3, cv::Scalar(70, 20, 200));
if (!rgb.isContinuous())
rgb = rgb.clone();
simaai::neat::Session session;
simaai::neat::InputOptions in;
in.format = "RGB";
in.width = rgb.cols;
in.height = rgb.rows;
in.depth = rgb.channels();
in.is_live = true;
session.add(simaai::neat::nodes::Input(in));
session.add(simaai::neat::nodes::Output());
// CORE LOGIC
// RunOptions controls how the async runner buffers and drops frames.
simaai::neat::RunOptions opt;
opt.queue_depth = queue_depth;
opt.overflow_policy = parse_drop_policy(argc, argv);
opt.output_memory = simaai::neat::OutputMemory::Owned;
opt.enable_metrics = true;
auto run = session.build(rgb, simaai::neat::RunMode::Async, opt);
// try_push never blocks; pair it with close_input + drain pull loop.
for (int i = 0; i < iters; ++i)
(void)run.try_push(rgb);
run.close_input();
int pulled = 0;
while (run.pull(/*timeout_ms=*/1000).has_value())
++pulled;
const auto stats = run.stats();
const auto input_stats = run.input_stats();
std::cout << "inputs_enqueued=" << stats.inputs_enqueued << "\n";
std::cout << "inputs_dropped=" << stats.inputs_dropped << "\n";
std::cout << "outputs_pulled=" << pulled << "\n";
std::cout << "avg_latency_ms=" << stats.avg_latency_ms << "\n";
std::cout << "avg_push_us=" << input_stats.avg_push_us << "\n";
std::cout << "renegotiations=" << input_stats.renegotiations << "\n";
std::cout << "[OK] 017_performance_tuning\n";
return 0;
} catch (const std::exception& e) {
std::cerr << "[FAIL] " << e.what() << "\n";
return 1;
}
}