0

I'm creating this code to time how long it takes a processor to do this operation for a school project. The problem was I couldn't get my loop working without printing every a result, if I didn't print the result of every a when multiplied by i, the processor would skip the loop. After solving this problem I tought than I am trying to benchmark my CPU and if I print every result it might affect on the performance or the time it takes to solve the operations. I've trying adding an if in the loop and only printing a when i=999999 but it doesn't work. Anybody can help?

#include <iostream>
#include <ctime>

using namespace std;

int main () {
    int start_s=clock();

    int i;
    for(i=0;i<1000000;i++){
        int a = i*434243;
        if(i = 999999){
            cout<<a;
        }

    }
    int stop_s=clock();
    cout << "time: "<< (stop_s-start_s)/double(CLOCKS_PER_SEC)*1000;

    cout<<"ms";
    system ("pause");
    return 0;
}
Ian
  • 1,221
  • 1
  • 18
  • 30
NaW
  • 89
  • 1
  • 5
  • 1
    ***How*** doesn't it work? What output did you expect? What did you really get? – Some programmer dude Jul 03 '18 at 10:17
  • 3
    if you remove the `cout`, when compiled with optimisations, the compiler will realise that the calculation of `a` has no observable side-effects and will remove it. Even without optimisation, 1,000,000 multiply operations will not take long on a 2GHz cpu. – Richard Hodges Jul 03 '18 at 10:17
  • Your `if` is not working? What sort of error are you getting? –  Jul 03 '18 at 10:22
  • I'm not getting any error I just get 0ms of my timer instead of 60 seconds or so if cout a – NaW Jul 03 '18 at 10:24
  • I've edited the code i've posted this is the code that gets me a time of 0 seconds – NaW Jul 03 '18 at 10:25
  • 2
    Setting aside the other bugs in your code: This is a basic manifestation of the as-if rule: code that ultimately achieves nothing can be optimised away, and just doing the same multiplication N times without ever showing or doing anything with the result achieves nothing. There are questions/answers about this, e.g. https://stackoverflow.com/questions/26771692/loop-with-a-zero-execution-time – underscore_d Jul 03 '18 at 10:34
  • Ok, I knew that but how do I fix it without having to cout every answer of a? – NaW Jul 03 '18 at 10:46
  • 1
    The "correct" answer for how long the loop takes **is 0ms**. Welcome to optimisation, where small changes make big differences. – Caleth Jul 03 '18 at 10:51
  • 2
    @NaW - The compiler can see that if you only output one value, the result is `cout << (999999 * 434243);`. And that probably takes 0 ms. Why compute a million values when you only need one? – Bo Persson Jul 03 '18 at 10:51
  • Is there any way for him to switch off the optimisation? –  Jul 03 '18 at 11:00
  • `if(i = 999999)` **assigns** the value 999999 to `i`, then checks whether `i` is 0 (which, of course, it never is). The code should be `if(i == 999999)`. – Pete Becker Jul 03 '18 at 12:49
  • Yeah, is there any way to turn off optimisation? – NaW Jul 03 '18 at 19:29
  • I don't need any of those values it's just I need the time it takes to calculate every operation when i is in different values, I said that I needed to cout one final value because I thought that if I did that it wouldn't optimise the code but also it wouldn't waste more CPU resources to print in my screen every result – NaW Jul 03 '18 at 19:32

5 Answers5

2

You have a mistake in the if expression. Should be i == 999999 instead of i = 999999

Andrii
  • 1,788
  • 11
  • 20
0

I don't have enough points to comment, but I think your problem comes from your vars type.

You should be doing this way :

double time = (double)(stop_s-start_s) * 1000.0 / CLOCKS_PER_SEC;
cout << "time: "<< time;

And change the type of stop_s and start_s to clock_t instead of int

Dampen59
  • 513
  • 2
  • 10
  • 1
    "due to the fact you're multiplying by 1000 and not 1000.0 the type is an int" wrong. There is a double earlier in the expression, so the multiplication occurs in the floating point realm. – underscore_d Jul 03 '18 at 10:36
0

It is less effect of optimisation but more so about std::cout being an expensive operation. Hence, when you remove cout from for loop, it takes less than 1 millisecond. However, with cout executing miliions of times makes your program really slow which is expected behaviour. You can add some more arithmatic operation where you are using "a" and you can print result outside the for loop so that "a" is still significant. E.g.

int i=0;
int a = 0;
for(;i<1000000;i++){
    a = i*434243;
    a += i;
    //cout<<a<<endl;
}
cout<<a<<" " <<i<<endl;

Related link here.

0

Actions that have no effect will be optimised away. The content of your loop only effects a local variable that is not used before it goes out out scope. (it is in-scope only inside the loop.) It is often difficult to create test code that does not optimise away to nothing. Alternatively you keep the code that you want but end up timing other actions such as saving the result as well. I suggest you try,

  • Put "int a;" outside the loop.
  • Use "volatile int a;"
  • Make a function and return a result from your loop.
  • Make the calculation in the loop dependent on a previous iteration. For example a = a * a;

You could, simply, turn down the optimisation, for example use -o0. However your performance will be poor and the timing would not be representative of normal real life code compiled with optimisation on.

0

Your loop has undefined behaviour, so strictly speaking anything is allowable.

warning: iteration 4946 invokes undefined behavior [-Waggressive-loop-optimizations]
     int a = i*434243;
note: within this loop
     for(int i=0;i<1000000;i++){
                 ~^~~~~~~~

Ignoring that, it's perfectly reasonable for code that can be calculated by the compiler to be, and the results put directly where used in the resulting program. Thus 0ms is a perfectly reasonable amount of time to do a calculation.

With a more precise clock, you may be able to observe it taking non-zero time, although that is dominated by the overhead of calling now

#include <iostream>
#include <chrono>

int main () {
    auto start = std::chrono::high_resolution_clock::now();

    for(unsigned i=0u;i<1000000u;i++){
        unsigned a = i*434243u;

    }
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff = end-start;
    std::cout << "Time: " << diff.count() << " s\n";

    int dummy;
    std::cin >> dummy;
    return 0;
}

Time: 1.869e-06 s

See it live

Caleth
  • 52,200
  • 2
  • 44
  • 75