Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change in precision due to use of inline function in C++ std::vector with g++ 4.4.7 20120313 in 32 bit

Tags:

c++

gcc

g++

I am compiling on centos5.9 32 bit (running on a 64 bit machine), targeting 32 bits. g++ version is 4.4.7, which is not the one shipped by default on centos5.9, but it can be downloaded with yum and is provided as part of the distro.

I have a very simple loop as follows

std::vector<double> result(n);
std::vector<double> values(n);
// here I compute values(). They are correct and I extensively noted 
// that there's nothing wrong there. The problem is here
result[0] = 0.0;
for ( int i = 0 ; i < n-1 ; ++i ) {
    result[i+1] = result[i]+values[i];
    // printf("x");
}

In a more complicated version of this code (which shows the exact same problem) I used the following operator for a class RealVector encapsulating a std::vector as a passthrough

inline double & operator[] (int index) { return data_[index]; }

The problem is that I found a tiny but relevant numerical difference in the result, depending if the operator[] is inline or not. Similarly, I also change the result if I uncomment the printf() line given above. Note that the problem does not occur in a centos59 64 bit with the same configuration, or if it occurs, it's below detectability.

Is it a compiler bug, or there's some subtle magic going on? I tried to check both the asm and the parse tree, but it's too complex to understand. I generally manage with C, but in C++ there's too much dark magic going on in the resulting files.

like image 841
Stefano Borini Avatar asked Feb 14 '23 16:02

Stefano Borini


1 Answers

Probably the old x87 fun feature again, 80 bits registers. Spilling that register to memory causes a rounding to 64 bits, and happens at unpredictable moments. Not at all unique to C++, C has the same issue. In Java it's "complicated"

Fixed by moving to 64 bit builds and SSE.

like image 117
MSalters Avatar answered Apr 28 '23 19:04

MSalters