Last active
October 28, 2015 09:10
-
-
Save LucHermitte/7f1b8d5dd61c861e6ef9 to your computer and use it in GitHub Desktop.
itk::VariableLengthVector micro benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <benchmark/benchmark.h> | |
#include <algorithm> | |
#include "itkVariableLengthVector.h" | |
static void clobber() { | |
asm volatile("" : : : "memory"); | |
} | |
static void BM_create_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
// benchmark::DoNotOptimize(&v); | |
benchmark::DoNotOptimize(&v[0]); | |
} | |
} | |
BENCHMARK(BM_create_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_create_VLV_and_fill(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_create_VLV_and_fill)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_copy_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2 = v; | |
benchmark::DoNotOptimize(&v2[0]); | |
} | |
} | |
BENCHMARK(BM_copy_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
// -- assign into empty | |
static void BM_assign_to_empty_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2; | |
benchmark::DoNotOptimize(&v2); | |
v2 = v; | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_assign_to_empty_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_defensive_assign_to_empty_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2; | |
benchmark::DoNotOptimize(&v2); | |
v2.DefensiveAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_defensive_assign_to_empty_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_manual_assign_to_empty_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2; | |
benchmark::DoNotOptimize(&v2); | |
v2.ManualAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_manual_assign_to_empty_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
// -- assign into allocated | |
static void BM_assign_to_allocated_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
benchmark::DoNotOptimize(&v2); | |
v2 = v; | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_assign_to_allocated_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_defensive_assign_to_allocated_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
benchmark::DoNotOptimize(&v2); | |
v2.DefensiveAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_defensive_assign_to_allocated_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_manual_assign_to_allocated_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
benchmark::DoNotOptimize(&v2); | |
v2.ManualAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_manual_assign_to_allocated_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_fast_assign_to_allocated_VLV(benchmark::State & state) { | |
while (state.KeepRunning()) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
benchmark::DoNotOptimize(&v[0]); | |
v.Fill(0); | |
clobber(); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
benchmark::DoNotOptimize(&v2); | |
v2.FastAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_fast_assign_to_allocated_VLV)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
// -- assign, allocations not benchmarked | |
static void BM_assign_alloc_not_benchmarked(benchmark::State & state) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
v.Fill(0); | |
while (state.KeepRunning()) { | |
v2 = v; | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_assign_alloc_not_benchmarked)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_defensive_assign_alloc_not_benchmarked(benchmark::State & state) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
v.Fill(0); | |
while (state.KeepRunning()) { | |
v2.DefensiveAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_defensive_assign_alloc_not_benchmarked)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_manual_assign_alloc_not_benchmarked(benchmark::State & state) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
v.Fill(0); | |
while (state.KeepRunning()) { | |
v2.ManualAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_manual_assign_alloc_not_benchmarked)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
static void BM_fast_assign_alloc_not_benchmarked(benchmark::State & state) { | |
itk::VariableLengthVector<double> v(state.range_x()); | |
itk::VariableLengthVector<double> v2(state.range_x()); | |
v.Fill(0); | |
while (state.KeepRunning()) { | |
v2.FastAssign(v); | |
benchmark::DoNotOptimize(&v2[0]); | |
clobber(); | |
} | |
} | |
BENCHMARK(BM_fast_assign_alloc_not_benchmarked)->Arg(1)->Arg(4)->Arg(16)->Arg(24); | |
BENCHMARK_MAIN(); | |
// Vim: let $LDFLAGS='-L/home/lhermitte/local/benchmark/lib -L/home/lhermitte/dev/Optims/install/ITK/reldeb/lib -Wl,-rpath /home/lhermitte/dev/Optims/install/ITK/reldeb/lib' | |
// Vim: let $LDLIBS='-lbenchmark -lITKCommon-4.9' | |
// Vim: let $CXXFLAGS='-I/home/lhermitte/local/benchmark/include -I/home/lhermitte/dev/Optims/install/ITK/reldeb/include/ITK-4.9 -O3 -fno-omit-frame-pointer -DNDEBUG' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./bench-copy-VLV | |
Run on (8 X 1998 MHz CPU s) | |
2015-10-27 12:23:00 | |
***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incure extra overhead. | |
Benchmark Time(ns) CPU(ns) Iterations | |
---------------------------------------------------------------------------- | |
BM_create_VLV/1 48 48 13461538 | |
BM_create_VLV/4 48 48 14462810 | |
BM_create_VLV/16 80 80 8333333 | |
BM_create_VLV/24 80 80 8750000 | |
BM_create_VLV_and_fill/1 53 53 13461538 | |
BM_create_VLV_and_fill/4 54 54 13461538 | |
BM_create_VLV_and_fill/16 89 89 7954545 | |
BM_create_VLV_and_fill/24 90 90 7954545 | |
BM_copy_VLV/1 108 108 6250000 | |
BM_copy_VLV/4 111 112 6481481 | |
BM_copy_VLV/16 162 162 4268293 | |
BM_copy_VLV/24 164 164 4166667 | |
BM_assign_to_empty_VLV/1 112 112 6481481 | |
BM_assign_to_empty_VLV/4 110 110 6250000 | |
BM_assign_to_empty_VLV/16 162 162 4375000 | |
BM_assign_to_empty_VLV/24 165 165 4268293 | |
BM_defensive_assign_to_empty_VLV/1 110 110 6481481 | |
BM_defensive_assign_to_empty_VLV/4 111 111 6481481 | |
BM_defensive_assign_to_empty_VLV/16 162 162 4268293 | |
BM_defensive_assign_to_empty_VLV/24 165 164 4268293 | |
BM_manual_assign_to_empty_VLV/1 109 109 6481481 | |
BM_manual_assign_to_empty_VLV/4 107 107 6481481 | |
BM_manual_assign_to_empty_VLV/16 161 162 4375000 | |
BM_manual_assign_to_empty_VLV/24 164 164 4268293 | |
BM_assign_to_allocated_VLV/1 110 110 6481481 | |
BM_assign_to_allocated_VLV/4 110 110 6250000 | |
BM_assign_to_allocated_VLV/16 164 164 4268293 | |
BM_assign_to_allocated_VLV/24 163 163 4268293 | |
BM_defensive_assign_to_allocated_VLV/1 110 110 6250000 | |
BM_defensive_assign_to_allocated_VLV/4 111 111 6250000 | |
BM_defensive_assign_to_allocated_VLV/16 161 161 4268293 | |
BM_defensive_assign_to_allocated_VLV/24 164 164 4268293 | |
BM_manual_assign_to_allocated_VLV/1 105 106 6730769 | |
BM_manual_assign_to_allocated_VLV/4 110 110 6250000 | |
BM_manual_assign_to_allocated_VLV/16 165 165 4268293 | |
BM_manual_assign_to_allocated_VLV/24 169 169 4166667 | |
BM_fast_assign_to_allocated_VLV/1 108 108 6250000 | |
BM_fast_assign_to_allocated_VLV/4 112 111 6034483 | |
BM_fast_assign_to_allocated_VLV/16 161 161 4375000 | |
BM_fast_assign_to_allocated_VLV/24 163 164 4375000 | |
BM_assign_alloc_not_benchmarked/1 6 6 116666667 | |
BM_assign_alloc_not_benchmarked/4 11 11 64814815 | |
BM_assign_alloc_not_benchmarked/16 16 16 43750000 | |
BM_assign_alloc_not_benchmarked/24 18 18 39772727 | |
BM_defensive_assign_alloc_not_benchmarked/1 7 7 102941176 | |
BM_defensive_assign_alloc_not_benchmarked/4 11 11 64814815 | |
BM_defensive_assign_alloc_not_benchmarked/16 16 16 42682927 | |
BM_defensive_assign_alloc_not_benchmarked/24 18 18 38043478 | |
BM_manual_assign_alloc_not_benchmarked/1 4 4 175000000 | |
BM_manual_assign_alloc_not_benchmarked/4 8 8 83333333 | |
BM_manual_assign_alloc_not_benchmarked/16 11 11 64814815 | |
BM_manual_assign_alloc_not_benchmarked/24 14 14 48611111 | |
BM_fast_assign_alloc_not_benchmarked/1 6 6 109375000 | |
BM_fast_assign_alloc_not_benchmarked/4 10 10 67307692 | |
BM_fast_assign_alloc_not_benchmarked/16 16 16 44871795 | |
BM_fast_assign_alloc_not_benchmarked/24 16 16 42682927 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Copy-Assignment operator */ | |
template< typename TValue > | |
VariableLengthVector< TValue > & | |
VariableLengthVector< TValue > | |
::operator=(const Self & v) | |
{ | |
// No self assignment test is done. Indeed: | |
// - the operator already resists self assignment through a strong exception | |
// guarantee | |
// - the test becomes a pessimization as we never write "v = v;". | |
ElementIdentifier const N = v.Size(); | |
this->SetSize( N, DontShrinkToFit(), DumpOldValues() ); | |
std::copy(&v.m_Data[0], &v.m_Data[N], &this->m_Data[0]); | |
return *this; | |
} | |
template< typename TValue > | |
VariableLengthVector< TValue > & | |
VariableLengthVector< TValue > | |
::DefensiveAssign(const Self & v) | |
{ | |
// No self assignment test is done. Indeed: | |
// - the operator already resists self assignment through a strong exception | |
// guarantee | |
// - the test becomes a pessimization as we never write "v = v;". | |
ElementIdentifier const N = v.Size(); | |
this->SetSize( N, DontShrinkToFit(), DumpOldValues() ); | |
if (this->m_Data != 0) { | |
std::copy(&v.m_Data[0], &v.m_Data[N], &this->m_Data[0]); | |
} | |
return *this; | |
} | |
template< typename TValue > | |
VariableLengthVector< TValue > & | |
VariableLengthVector< TValue > | |
::ManualAssign(const Self & v) | |
{ | |
// No self assignment test is done. Indeed: | |
// - the operator already resists self assignment through a strong exception | |
// guarantee | |
// - the test becomes a pessimization as we never write "v = v;". | |
ElementIdentifier const N = v.Size(); | |
this->SetSize( N, DontShrinkToFit(), DumpOldValues() ); | |
for (ElementIdentifier i = 0; i != N; ++i) { | |
m_Data[i] = v.m_Data[i]; | |
} | |
return *this; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment