This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: 4.3.0 strange problem with computation and optimization
- From: Tim Prince <tprince at myrealbox dot com>
- To: Lasse Kliemann <lasse-list-gcc-2008 at mail dot plastictree dot net>
- Cc: gcc-help at gcc dot gnu dot org
- Date: Fri, 14 Mar 2008 18:19:43 -0700
- Subject: Re: 4.3.0 strange problem with computation and optimization
- References: <20080312173125.GE2471@lasse.mail.plastictre.net>
Lasse Kliemann wrote:
> Greetings,
>
> I have a C++ program that does some linear programming optimization. Out of
> this linear programming, I get a vector of doubles `x' and a double `opt'
> that should be the sum of the entries in `x' (`x' is the solution vector and
> `opt' is the optimal value). As a consistency chek, I compute the sum of the
> elements of `x' and then compute the difference to `opt'. It should be close
> to zero. Here is a snippet from the code:
>
> double sum = 0;
> const double *x = model->getColSolution();
> for (unsigned int j=0; j<m; ++j) sum += x[j];
> double d=opt-sum;
> cout << "difference: " << d << endl;
>
> If I compile that with g++ version 4.3.0 and -O0, -O1, or -Os, everything
> looks OK; in rare cases the difference is zero, and in most cases it is a
> very small number. Now, if I compile that with -O2 or -O3, the difference is
> *always* printed to be zero, which I presume is wrong.
>
> Now for the weird part. Consider the following code:
>
> double sum = 0;
> const double *x = model->getColSolution();
> for (unsigned int j=0; j<m; ++j) sum += x[j];
> double d=opt-sum;
> cout << "difference: " << d << endl;
> cout << "difference: " << d << endl;
>
> That is the above with the last line repeated. This works as expected with
> any optimization, i.e., the same (in most cases: non-zero) number is printed
> twice.
>
> There are other strange ways to get this fixed, for example insert a
> statement like
>
> cout << endl;
>
> between the computation of the sum and the output of `d'.
>
> I tried to construct a minimal example by writing `x' and `opt' to a file and
> reading it in by a small program which only does the summing up, takes the
> difference and prints it out. Unfortunately, the phenomenon does not show up
> there. Now, I can provide the program where the problem occurred, it's no
> more than 70 lines, but it must be linked against the CLP library (from the
> coin-or.org project).
>
> Hopefully, someone can give me a hint how to track this down further. The
> profile is quite sharp, I think: -O0, -O1, -O2 work, but -O2 and -O3 don't.
> Operating system is Linux 2.6.x on a Intel Xeon E5310.
I don't recall if this is a repeat of a previous post. As you talk about
differences with optimization level, I assume you have not specified
-mfpmath=sse, and your sum variable is implicitly promoted to long double
in some cases. This issue has been around ever since the 68881 and 80287
were invented, so there are plenty of places to read about it. I believe
others have informed you that gcc is not about to disable support for old
CPUs, or even optimization for not so old ones, simply because Microsoft
has hidden the issue from you.