1
\$\begingroup\$

I'm writing some code to take high precision timings of a function call

for (int i = 0; i < iterations; i++) {
    beginTime = high_resolution_clock::now();

    CallFunc(functionPtr, otherParamaters ...); // inline function call to do the timed function

    endTime = high_resolution_clock::now();
    elapsedTime = duration_cast<duration<double>>(endTime - beginTime);
    timings.push_back(elapsedTime.count());
}

However some of the functions I'm timing run so fast the clock can't pick them up, it ends up just writing a load of 0s

I Had the idea to do several repetitions of the function call per timing, to try to get a numerical time I could then divide down past the resolution of the clock, but I don't want to penalize the accuracy of the timing for functions that don't need these repetitions

My solution was to use preprocessor #ifs

for (int i = 0; i < iterations; i++) {
    beginTime = high_resolution_clock::now();

#if repetitions > 1
    for (int i = 0; i < repetitions; i++) {
#endif 
        CallFunc(functionPtr, otherParamaters ...); // inline function call to do the timed function
#if repetitions > 1
    }
#endif    
    endTime = high_resolution_clock::now();
    elapsedTime = duration_cast<duration<double>>(endTime - beginTime);
    timings.push_back(elapsedTime.count());
}

My question is, is this kind of optimization silly? Is the compiler likely to do this for me anyway?

EDIT: repetitions is a const int

\$\endgroup\$
4
  • 3
    \$\begingroup\$ Is repititions a compile time constant? If yes, it's probably not necessary. The compiler can unroll the loop itself. \$\endgroup\$
    – Mikael H
    Jun 15, 2020 at 12:50
  • \$\begingroup\$ Welcome to code review where we review working code from one of your projects and provide suggestions on how to improve your code. As pointed out in the comment by @MikaelH there is some code here that is missing that is necessary, and that prevents us from doing a good review. This makes the question off-topic for code review. I would suggest first searching stackoverflow.com for an answer to your question, if an answer doesn't doesn't exist then ask the question on stackoverflow, but make sure to follow their guidelines. \$\endgroup\$
    – pacmaninbw
    Jun 15, 2020 at 15:48
  • \$\begingroup\$ Suggestion, this is not a compile time decision, I would have an if statement based on a first test of elapsed time, if elapsed time is zero, do it in a loop, if elapsed time is not zero you have enough resolution to do it the other way. When I had a job where CPU processor time mattered we measured performance using loops of basic instructions in operations over a million times. \$\endgroup\$
    – pacmaninbw
    Jun 15, 2020 at 15:54
  • 2
    \$\begingroup\$ @Jake: Use github.com/google/benchmark . Don't try to write microbenchmarking code on your own; your results won't mean anything. \$\endgroup\$ Jun 15, 2020 at 17:07

1 Answer 1

2
\$\begingroup\$

Notational suggestion: if insisting on a bracketed controlled statement, favour

#if 0 < repetitions
# if 1 < repetitions
    for (int i = 0; i < repetitions; i++)
# endif
    {
        CallFunc(functionPtr, otherParamaters …); // inline call to timed function
    }
#endif
\$\endgroup\$
2
  • \$\begingroup\$ Why not simply #if repetitions != 1? That would make the other #if redundant. \$\endgroup\$ Jun 15, 2020 at 21:21
  • 2
    \$\begingroup\$ @RolandIllig it is about explicit (my preference) vs. implicit, covered by your suggestion. Using just repetitions > 1 to control the visibility gets the statement executed once for repetitions 0 - makes me icky. That is handled by the original for construct pre-processor controlled as per your suggestion - I'd feel pressed to leave a code comment. And think it better to code the blatantly obvious way instead of explaining. \$\endgroup\$
    – greybeard
    Jun 16, 2020 at 3:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.