Search code examples
c++c++-chrono

Dividing two chrono::durations to get fraction


To calculate the possible speedup (Amdahl) I need the fraction of the parallelizable part of my code compared to the total sequential runtime. I timed the execution using the chrono.h library and got the total sequential runtime and parallelizable part runtime as chrono::duration in nanoseconds.

Now I need to divide these two durations to get the percentage of possible parallelizable part.

e.g.

auto seqStartTime = std::chrono::steady_clock::now();

   // Some code, non parallelizable

auto parStartTime = std::chrono::steady_clock::now();
   // Parallelizable sequential code
auto parEndTime = std::chrono::steady_clock::now();

auto timeTakenPar = std::chrono::duration_cast<std::chrono::nanoseconds>(parEndTime - parStartTime);


   // More sequential code possible

auto seqEndTime = std::chrono::steady_clock::now();
auto timeTakenSeq = std::chrono::duration_cast<std::chrono::nanoseconds>(seqEndTime - seqStartTime);

// auto frac = timeTakenPar / timeTakenSeq (??)

Any idea how to do that?

Simply dividing won't do the trick, since as far as I understood, this only returns the number of times the right hand side duration after conversion fits into the left hand side duration. In this case obviously zero, since the total runtime is on the rhs and parallelizable part runtime on the lhs.

I also tried using .count() before dividing, but still ended up with 0 as result.

Any help is highly appreciated!


Solution

  • <chrono> supports different numerical representations, including double, there is even support for literals like 2.5ms. Unfortunately there is no nanoseconds<double> shortcut and the cast is more wordy.

    #include <chrono>
    #include <iostream>
    
    using namespace std::chrono;
    using namespace std::chrono_literals;
    
    int main() {
        auto parStartTime = std::chrono::steady_clock::now();
        auto parEndTime = parStartTime + 12ns;  // Dummy value
    
        using dnanoseconds = std::chrono::duration<long double, std::nano>;
        auto dur = parEndTime - parStartTime;
    
        std::cout << "Int/int nanoseconds:" << dur / (24ns) << '\n';
        std::cout << "Int/double nanoseconds:" << dur / (24.0ns) << '\n';
        std::cout << "Double/double nanoseconds:"
                  << std::chrono::duration_cast<dnanoseconds>(dur) / (24.0ns) << '\n';
        std::cout << "Double/int nanoseconds:"
                  << std::chrono::duration_cast<dnanoseconds>(dur) / 24ns << '\n';
    }
    

    outputs:

    Int/int nanoseconds:0
    Int/double nanoseconds:0.5
    Double/double nanoseconds:0.5
    Double/int nanoseconds:0.5