There is a loop in my code that iterates 100 million times (required for 100 million replications of a simulation model). For each of the 100 million iterations, I retrieve a value from an array (myarray
) by indexing on an integer variable named age
. Due to the length of the array, it is only valid to index myarray[age]
for age=0,...,99
. However, the actual domain of age
is 0,...,inf
.
So, I have the following function
int tidx(const int& a) {
return std::min(a,99);
}
which allows indexing by myarray[tidx(age)]
.
How could I do this more efficiently?
[PERF OUTPUT BELOW]
An example of building a source file that illustrates the compiler flags I'm using:
Building file: ../SAR.cpp
Invoking: GCC C++ Compiler
g++ -O3 -Wall -c -fmessage-length=0 -Wno-sign-compare -fopenmp -MMD -MP -MF"SAR.d" -MT"SAR.d" -o"SAR.o" "../SAR.cpp"
Finished building: ../SAR.cpp
From perf record
followed by perf report
:
Samples: 280 of event 'cycles', Event count (approx.): 179855989
24.78% pc2 libc-2.17.so [.] __GI_____strtod_l_internal
11.35% pc2 pc2 [.] samplePSA(int, double, int, NRRan&)
6.67% pc2 libc-2.17.so [.] str_to_mpn.isra.0
6.15% pc2 pc2 [.] simulate4_NEJMdisutilities(Policy&, bool)
5.68% pc2 pc2 [.] (anonymous namespace)::stateTransition(double const&, int const&, int&, double const&, bool const&, bool&, bo
5.25% pc2 pc2 [.] HistogramAges::add(double const&)
3.73% pc2 libstdc++.so.6.0.17 [.] std::istream::getline(char*, long, char)
3.02% pc2 libstdc++.so.6.0.17 [.] std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_
2.49% pc2 [kernel.kallsyms] [k] 0xffffffff81043e6a
2.29% pc2 libc-2.17.so [.] __strlen_sse2
2.00% pc2 libc-2.17.so [.] __mpn_lshift
1.72% pc2 libstdc++.so.6.0.17 [.] __cxxabiv1::__vmi_class_type_info::__do_dyncast(long, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::
1.71% pc2 libc-2.17.so [.] __memcpy_ssse3_back
1.67% pc2 libstdc++.so.6.0.17 [.] std::locale::~locale()
1.65% pc2 libc-2.17.so [.] __mpn_construct_double
1.38% pc2 libc-2.17.so [.] memchr
1.29% pc2 pc2 [.] (anonymous namespace)::readTransitionMatrix(double*, std::string)
1.27% pc2 libstdc++.so.6.0.17 [.] std::string::_M_mutate(unsigned long, unsigned long, unsigned long)
1.15% pc2 libc-2.17.so [.] round_and_return
1.02% pc2 libc-2.17.so [.] __mpn_mul
1.01% pc2 libstdc++.so.6.0.17 [.] std::istream::sentry::sentry(std::istream&, bool)
1.00% pc2 libc-2.17.so [.] __memcpy_sse2
0.85% pc2 libstdc++.so.6.0.17 [.] std::locale::locale(std::locale const&)
0.85% pc2 libstdc++.so.6.0.17 [.] std::string::_M_replace_safe(unsigned long, unsigned long, char const*, unsigned long)
0.83% pc2 libstdc++.so.6.0.17 [.] std::locale::locale()
0.73% pc2 libc-2.17.so [.] __mpn_mul_1
From perf stat
:
Performance counter stats for './release/pc2':
62.449034 task-clock # 0.988 CPUs utilized
49 context-switches # 0.785 K/sec
3 cpu-migrations # 0.048 K/sec
861 page-faults # 0.014 M/sec
179,240,478 cycles # 2.870 GHz
58,909,298 stalled-cycles-frontend # 32.87% frontend cycles idle
<not supported> stalled-cycles-backend
320,437,960 instructions # 1.79 insns per cycle
# 0.18 stalled cycles per insn
70,932,710 branches # 1135.850 M/sec
697,468 branch-misses # 0.98% of all branches
0.063228446 seconds time elapsed
I would appreciate any comments. I need to learn how to interpret/read this information, so any tips that might help me get started would be appreciated.