0

My question is: is there an option on gcc Linux that behaves like fast-math on gcc AIX (in this particular case)?

I had to migrate from AIX to Linux, a couple of hundred C and C++ programs. On AIX we used xlc to compile. On Linux we will use gcc. In some programs, we have floating point operations, I know that floating point could give different results on different platforms, but I'm curious about a situation where gcc gives me a different result than xlc (which is normal), when I add --ffast-math option it gives me the result that I want, but on Linux, the same option doesn't have any impact on the result. Here's the code and what I've done:

#include <stdio.h>

int main () {
double importe, franja, base, porcentaje, irpf;

printf("/*-----------------*/\n");

importe = 10562.5;
franja = 3.0;
base = 2226.0;
porcentaje = 10.0;
irpf = franja * base * ( porcentaje/ 100 );
printf("Redondeo1 [%.16f]\n", irpf );

importe -= franja * base;
franja = 5;
porcentaje = 15.0;
irpf += importe * ( porcentaje / 100 );
printf("Redondeo2 [%.16f]\n", irpf );

return 0;
}

Compiled with

AIX> /usr/vac/bin/xlc -o redondo.xlc redondo.c

and executed

AIX> redondo.xlc
/*-----------------*/
Redondeo1 [667.8000000000000682]
Redondeo2 [1250.4750000000001364]

Then I tried a first step, compiling with gcc on AIX

AIX> gcc -o redondo.gcc redondo.c

executing it, gives a difference on the second result

AIX> redondo.gcc
/*-----------------*/
Redondeo1 [667.8000000000000682]
Redondeo2 [1250.4749999999999091]

so I tried -ffast-math

AIX> gcc  -ffast-math -o redondo.gcc-ffast-math  redondo.c

and executed

AIX> redondo.gcc-ffast-math
/*-----------------*/
Redondeo1 [667.8000000000000682]
Redondeo2 [1250.4750000000001364]

solves the situation ....on AIX. When I tried to replicate the solution on Linux, it always gives the same result:

Linux> gcc -o redondo.gcc  redondo.c
Linux> redondo.gcc
/*-----------------*/
Redondeo1 [667.8000000000000682]
Redondeo2 [1250.4749999999999091]
Linux> gcc -ffast-math -o redondo.gcc-ffast-math  redondo.c
Linux> redondo.gcc-ffast-math
/*-----------------*/
Redondeo1 [667.8000000000000682]
Redondeo2 [1250.4749999999999091]

I know that floating point is non deterministic, not every number is representable, the results depends on the system architecture and the compiler and libraries, etc. etc. .... but perhaps, there's and option on gcc Linux that behaves like fast-math on gcc AIX. I tried a lot of gcc options (frounding-math, mfpmath, contract, store, excess, m387, unsafe, reciprocal, finite, ffast-math) and even reordering the operations, with no success.


AIX info:

AIX> oslevel -s
7100-04-05-1720

AIX> prtconf
System Model: IBM,9009-42A
Processor Type: PowerPC_POWER9
Processor Implementation Mode: POWER 8
Processor Version: PV_8_Compat
Number Of Processors: 2
Processor Clock Speed: 2750 MHz
CPU Type: 64-bit
Kernel Type: 64-bit
LPAR Info: 24 dc4_bpdesa6
Memory Size: 8192 MB
Good Memory Size: 8192 MB
Platform Firmware level: VL910_135
Firmware Version: IBM,VL910_135
Console Login: enable
Auto Restart: true
Full Core: false

AIX> gcc --version
gcc (GCC) 4.2.0
Copyright (C) 2007 Free Software Foundation, Inc.

Linux info:

Linux> cat /etc/os-release
NAME="Red Hat Enterprise Linux Server"
VERSION="7.5 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="7.5"
PRETTY_NAME="Red Hat Enterprise Linux"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.5:GA:server"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.5
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.5"

Linux> gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
MRicciar
  • 49
  • 4
  • 2
    `1250.4749999999999091` is effectively equivalent to `1250.475`. Is this Intel vs. PowerPC? – tadman Oct 02 '19 at 17:26
  • 1
    This may or may not be useful as background reading: https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/ – NPE Oct 02 '19 at 17:26
  • 1
    There is no specific question in your post. What are you asking? – Eric Postpischil Oct 02 '19 at 17:27
  • My question is: is there and option on gcc Linux that behaves like fast-math on gcc AIX (in this particular case)? – MRicciar Oct 02 '19 at 18:48
  • 1
    @tadman yes, is Intel vs. PowerPC. ANd in fact, rounding 1250.4749999999999091 to 2 decimals yields 1250.47 as result (because 3rd decimal is < 5), but rounding 1250.4750000000001364 gives 1250.48 (3rd decimal is >= 5). – MRicciar Oct 02 '19 at 18:53
  • 1
    If this is an unusual question (I can't tell), then one of the people who probably know the answer is Segher Boessenkool. He is one of the GCC PowerPC maintainers, and he hangs out on the [GCC Help mailing list](https://gcc.gnu.org/ml/gcc-help/). – jww Oct 02 '19 at 19:09
  • Did you read the article linked by NPE? It should give some pointers. Additionally these pages might be helpful: ["What does gcc's ffast-math actually do?"](https://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do) and [Semantics of Floating Point Math in GCC](https://gcc.gnu.org/wiki/FloatingPointMath). – the busybee Oct 02 '19 at 19:36
  • 2
    You're going to get ever so slightly different values on Intel vs. PowerPC vs. ARM, so I'd just expect this rather than fuss about it. How many places do you need? Work with that constraint, not the maximal version. Intel uses 64 or 80-bit floats depending on context, PowerPC might be different. – tadman Oct 02 '19 at 20:07
  • Yes I read (some of) NPE article, and also read Semantics of fp ..... and what ffast-math do..... my problem is that ffast-math on AIX does something that fast-math on LInux does not..... perhaps I could contact Segher Boessenkool and he can direct me to the GCC Intel maintainer. – MRicciar Oct 02 '19 at 20:13
  • 1
    Both **GCC 4.2 and 4.8 are obsolete**, unsupported today, variants of GCC. Why don't you use the more recent [GCC 9](https://gcc.gnu.org/gcc-9/) ?? I guess that its floating point support is better, since the GCC community worked a big lot on better floating point support. I strongly recommend upgrading your GCC (perhaps by compiling its source code) – Basile Starynkevitch Oct 02 '19 at 20:31
  • Yes, I should probably use the latest version, sadly I don't control the environment platform, it's operated by my customer (I only migrate the code). I'll ask them if they could install the newest version. Thnks. – MRicciar Oct 02 '19 at 20:44
  • 1250.4750000000001364 = 0x1.389e666666667p10 and 1250.4750000000001364 = 0x1.389e666666666p10 which differ only in the last bit – phuclv Oct 03 '19 at 02:13
  • IMO, relying on fast-math to get bit identical results is too much like gambling. It's already difficult enough to get bit identical result with fpstrict IEEE compliance. fast-math enables many possible arrangements, like changing operation order (despite being not transitive); using fma (fused-multiply-add) if available etc... so the chances that two different compilers use the exact same tricks is very narrow. – aka.nice Oct 04 '19 at 07:31
  • I understand what you said aka.nice , but using fast-math on gcc for AIX get bit identical results as xlc (at least in this case).... so thats why I asked if could by something similar on gcc for Linux. Now I agree that it was pure luck, as you said. – MRicciar Oct 04 '19 at 14:39

0 Answers0