mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-04-14 08:16:01 -04:00
I'm seeing what is possible performance-wise in the current C++ before trying out Go and Rust implementations. * use the google benchmark framework and some real data. * use release builds - I hadn't done this in a while, and there were a few compile errors that manifested only in release mode. Update the readme to suggest using a release build. * optimize the varint decoder and SampleIndexIterator to branch less. * enable link-time optimization for release builds. * add some support for feedback-directed optimization. Ideally "make" would automatically produce the "generate" build outputs with a different object/library/executable suffix, run the generate benchmark, and then produce the "use" builds. This is not that fancy; you have to run an arcane command: alias cmake='cmake -DCMAKE_BUILD_TYPE=Release' cmake -DPROFILE_GENERATE=true -DPROFILE_USE=false .. && \ make recording-bench && \ src/recording-bench && \ cmake -DPROFILE_GENERATE=false -DPROFILE_USE=true .. && \ make recording-bench && \ perf stat -e cycles,instructions,branches,branch-misses \ src/recording-bench --benchmark_repetitions=5 That said, the results are dramatic - at least 50% improvement. (The results weren't stable before as small tweaks to the code caused a huge shift in performance, presumably something something branch alignment something something.)
67 lines
2.5 KiB
C++
67 lines
2.5 KiB
C++
// This file is part of Moonfire NVR, a security camera network video recorder.
|
|
// Copyright (C) 2016 Scott Lamb <slamb@slamb.org>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// In addition, as a special exception, the copyright holders give
|
|
// permission to link the code of portions of this program with the
|
|
// OpenSSL library under certain conditions as described in each
|
|
// individual source file, and distribute linked combinations including
|
|
// the two.
|
|
//
|
|
// You must obey the GNU General Public License in all respects for all
|
|
// of the code used other than OpenSSL. If you modify file(s) with this
|
|
// exception, you may extend this exception to your version of the
|
|
// file(s), but you are not obligated to do so. If you do not wish to do
|
|
// so, delete this exception statement from your version. If you delete
|
|
// this exception statement from all source files in the program, then
|
|
// also delete it here.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
// recording-bench.cc: benchmarks of the recording.h interface.
|
|
|
|
#include <benchmark/benchmark.h>
|
|
#include <gflags/gflags.h>
|
|
|
|
#include "recording.h"
|
|
#include "testutil.h"
|
|
|
|
DECLARE_bool(alsologtostderr);
|
|
|
|
static void BM_Iterator(benchmark::State &state) {
|
|
using moonfire_nvr::ReadFileOrDie;
|
|
using moonfire_nvr::SampleIndexIterator;
|
|
// state.PauseTiming();
|
|
std::string index = ReadFileOrDie("../src/testdata/video_sample_index.bin");
|
|
// state.ResumeTiming();
|
|
while (state.KeepRunning()) {
|
|
SampleIndexIterator it(index);
|
|
while (!it.done()) it.Next();
|
|
CHECK(!it.has_error()) << it.error();
|
|
}
|
|
state.SetBytesProcessed(int64_t(state.iterations()) * int64_t(index.size()));
|
|
}
|
|
BENCHMARK(BM_Iterator);
|
|
|
|
int main(int argc, char **argv) {
|
|
FLAGS_alsologtostderr = true;
|
|
|
|
// Sadly, these two flag-parsing libraries don't appear to get along.
|
|
// google::ParseCommandLineFlags(&argc, &argv, true);
|
|
benchmark::Initialize(&argc, argv);
|
|
|
|
google::InitGoogleLogging(argv[0]);
|
|
benchmark::RunSpecifiedBenchmarks();
|
|
return 0;
|
|
}
|