Is it an out of order execution case?

144 views Asked by At

Consider the code below.


#include <iostream>
#include <random>
#include <chrono>
#include <memory>
const int N = 1 << 28;
int main()
{
    const int seed = 0;
    std::mt19937 gen;
    std::uniform_real_distribution<double> dis;
    std::normal_distribution<double> normal;
    std::unique_ptr<bool[]> array = std::unique_ptr<bool[]>(new bool[N]);

    for (int i = 0; i < N; i++)
    {
        if (dis(gen) > 0.5)
            array[i] = true;
        else
            array[i] = false;
    }

    int sum = 0;
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < N; i++)
    {
        if (array[i])
            sum++;
    }
    auto t2 = std::chrono::high_resolution_clock::now();

    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << " microsecond" << std::endl;
    std::cout << sum << std::endl;




         sum = 0;
     t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < N; i++)
    {
            sum+=array[i];
    }
     t2 = std::chrono::high_resolution_clock::now();

    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << " microsecond" << std::endl;
    std::cout << sum << std::endl;
}

If I comment lines with std::cout << sum << std::endl; then the execution times will shown as zeros ( or close enough) . I have checked it on different compilers, including icpc, icl (v19.1.2) and g++ ( v9.2) with O3 compilation flag.

Is this an example of out-of-order (dynamic) execution?

1

There are 1 answers

5
463035818_is_not_an_ai On

Without the lines

std::cout << sum << std::endl; 

The compiler will realize that removing this

for (int i = 0; i < N; i++)
{
    if (array[i])
        sum++;
}

has no observable effect (same is true for both loops that calcualte sum). Hence also this

for (int i = 0; i < N; i++)
    {
        if (dis(gen) > 0.5)
            array[i] = true;
        else
            array[i] = false;
    }

can be removed without observable effect.

This is an example of the so called as-if-rule. In a nutshell, as long as the observable behavior does not change the compiler can do anything. For more details, see What exactly is the "as-if" rule?

Measuring the runtime does not count as observable behavior of the program by the way.