0

I run the same code in VS code by internalConsole and externalConsole. But they give different results.

The platform is:

Visual Studio Code:1.64.2(system setup)
OS: Windows NT x64 10.0.19042
gcc: 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

InternalConsole is launched by Coderunner and returns:

PS D:\coding\notes\DataStructure\01> g++ '02duoxiangshi.cpp' -o '02duoxiangshi.exe' -Wall -O2 -m64 -static-libgcc -fexec-charset=GBK ; if ($?) { &'./02duoxiangshi.exe' } 
ticks1 = 1346.000000
duration1 = 1.35e-007
ticks2 = 0.000000
duration2 = 0.00e+000

ExternalConsole is launched by pressing F5 and returns:

ticks1 = 1385.000000
duration1 = 1.39e-07
ticks2 = 191.000000
duration2 = 1.91e-08

Problems: The ticks2 and durations2 in the former is 0, which is wrong, while the latter seems right.

I find out it maybe caused by the -O2 option in g++ '02duoxiangshi.cpp' -o '02duoxiangshi.exe' -Wall -O2 -m64 -static-libgcc -fexec-charset=GBK ; if ($?) { &'./02duoxiangshi.exe' } by testing. By deleting -O2, the result is:

PS D:\coding\notes\DataStructure\01> g++ '02duoxiangshi.cpp' -o '02duoxiangshi.exe' -Wall -m64 -static-libgcc -fexec-charset=GBK ; if ($?) { &'./02duoxiangshi.exe' }     
ticks1 = 1489.000000
duration1 = 1.49e-007
ticks2 = 192.000000
duration2 = 1.92e-008

The code file name is 02duoxiangshi.cpp. The code is as follows:

#include <stdio.h>
#include <time.h>
#include <math.h>
#include<stdlib.h>

clock_t start, stop;

double duration;

#define MAXN 10
#define MAXK 1e7

double f1(int n, double a[], double x );
double f2(int n, double a[], double x );

int main ()
{
    int i;
    double a[MAXN];
    for (i = 0; i < MAXN; i++)
    {
        a[i] = (double)i;
    }
    start = clock();
    for (i = 0; i < MAXK; i++)
    {
        f1(MAXN - 1, a, 1.1);
    }
    stop = clock();
    duration = ((double)(stop - start)) / CLK_TCK / MAXK;
    printf("ticks1 = %f\n", (double)(stop - start));
    printf("duration1 = %6.2e\n", duration);

    start = clock();
    for (i = 0; i < MAXK; i++)
    {
        f2(MAXN - 1, a, 1.1);
    }
    stop = clock();
    duration = ((double)(stop - start)) / CLK_TCK / MAXK;
    printf("ticks2 = %f\n", (double)(stop - start));
    printf("duration2 = %6.2e\n", duration);

    system("pause");
    return 0;
}

double f1( int n, double a[], double x )
{
    int i;
    double p = a[0];
    for (i = 1; i <= n; i++)
    {
        p += a[i] * pow(x, i);
    }
    return p;
}

double f2( int n, double a[], double x )
{
    int i;
    double p = a[n];
    for (i = n; i > 0; i--)
    {
        p = a[i - 1] + x * p;
    }
    return p;
}

Questions:

  1. Is it because of the -O2?
  2. Should I delete it from now on?
yangtzech
  • 45
  • 6
  • 1
    _"Problems: The ticks2 and durations2 in the former is 0, which is wrong"_ Why do you think that is wrong? You are timing code that does nothing, according to the as-if rule. The code you are timing has no effect, and can be removed by the optimizer. – Drew Dormann Feb 23 '22 at 13:46
  • 1
    All you really did was test how good/smart the optimizer is. – PaulMcKenzie Feb 23 '22 at 13:47
  • @DrewDormann . Thanks for your explanation. I did search and find that **-O2** is used for optimization. The code is from a DataStructure Lesson i am learning, used to demonstrate that the efficiency of solving problems is related to the cleverness of the algorithm. Therefore I want to time the the cost of the function. – yangtzech Feb 23 '22 at 14:06
  • @PaulMcKenzie . doesn't ticks1 test how good function f1 is? Why is only ticks2 is 0? – yangtzech Feb 23 '22 at 14:08
  • With a smart enough optimizer, both `ticks1` and `ticks2` will be very low. Change `-O2` to `-O3` and you will likely see all measurements become significantly small. Again, because both measurements are measuring the time to do _nothing of significance_. "Do lots of math, and dispose of the results" is equivalent to "Do nothing" [according to the as-if rule](https://stackoverflow.com/questions/15718262/what-exactly-is-the-as-if-rule). – Drew Dormann Feb 23 '22 at 14:26
  • @yangtzech -- I have seen compiler optimizers figure out what your function is doing, and optimize everything and simply return the final result. Some time ago, I had posted an answer where the code was supposed to rearrange digits of a number -- the compiler figured out what the loop I wrote did, and the generated assembly removed the entire loop and just had a `ret value`. So the other scenario is that the loop was removed, and instead, the compiler was smart enough to detect what your loop is doing, and thus returned the result without having to loop. – PaulMcKenzie Feb 23 '22 at 14:45
  • @PaulMcKenzie -- I don't know much about optimizer earlier and till not much, but what u have said do enhance my understandings. Thanks! – yangtzech Feb 24 '22 at 01:42

0 Answers0