Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

#pragma float_control issue

Gordon_F_
Beginner
783 Views

Hello,

I am running into a problem I am at a loss to explain. I'm hoping somebody can point me to what I'm doing incorrectly.

I have a simple function and a main program in C, as follows:

1) Simple function in a file a.c:

#include <stdio.h>
#include <float.h>
#include <limits.h>
#include <math.h>

#ifdef __INTEL_COMPILER
#pragma float_control(precise,on,push)
#endif


static double
dstore(double x)
{
   return (x);
}

int myfunc()
{
   double x;
   x = 1.0;
   while (dstore(x / 2.0) != 0.0) {
      x /= 2.0;
   }
    (void)printf("  smallest positive number = %13.5le\n ", x);
   return 0;
}
#ifdef __INTEL_COMPILER
#pragma float_control(pop)
#endif

2) Main program in file b.c:

int myfunc();

int main()
{
   myfunc();
   return 0;
}

If I compile this on Win64 using the command

icl /O3 a.c b.c

then run the resulting executable I get

smallest positive number =  2.22507e-308

However, if I combine a.c and b.c into a single file and run it, I get

smallest positive number =  4.94066e-324

What I need to do is to set the function in the middle of a library that can be called by an application. The idea of the pragma is that the pragma will ensure that I get 4.94066e-324 no matter how the application is compiled. But what I'm finding out is that even with the pragma, if the function and the main program are in separate files it's as if the pragma isn't really working. It only works when called from within the same file.

Would somebody be kind enough to explain to me why this is happening and how I can correct this so that, in separate files, I still get the value 4.94066e-324 in my function?

Thanks.

0 Kudos
5 Replies
TimP
Honored Contributor III
783 Views

The FTZ intrinsics might do this more reliably.  pragma float_control, for Microsoft compatibility, presumably applies only on Windows.

If you try to control FTZ with compile options, it works only in the main program.  It looks like you're seeing a similar effect.

0 Kudos
Gordon_F_
Beginner
783 Views

Tim,

Thanks for the quick reply. Just to confirm, are you referring to the function

_MM_SET_FLUSH_ZERO_MODE (_MM_FLUSH_ZERO_OFF);
_MM_SET_FLUSH_ZERO_MODE (_MM_FLUSH_ZERO_ON);

In other words, from what I understand, in all my functions between the pragma(...push) and pragma(pop) statements - there are many functions there - I need to first set the flush mode to off, then at the end of the function set it to on again?

Thanks!

0 Kudos
TimP
Honored Contributor III
783 Views

Yes, those intrinsics turn off and on the abrupt underflow mask bit directly (presumably involving pipeline flush).  Library functions ought already to be written to save and restore the state of any bits in the msrdtc which they modify.

Beginning with Sandy Bridge (corei7-2) the need to set abrupt underflow for performance in normal situations is supposed to have been eliminated, so it won't surprise me if convenient methods to handle this pragma aren't fully supported.

Another possibility is that /fp:strict may need to be set to avoid the compiler conflicting with these settings in some situations.  MSVC++ doesn't have any compile modes which conflict as icc -fast options do; CL /fp:fast is about equivalent to ICL /fp:source

0 Kudos
SergeyKostrov
Valued Contributor II
783 Views
>>...f the function and the main program are in separate files it's as if the pragma isn't really working... Try to use CRT functions, like '_controlfp' or like that ( declared in 'float.h' ), to control precision of FP-calculations. I used '#pragma float_control' some time ago and it did not work ( also it is not portable solution ). That is why I decided to use the CRT function for that task.
0 Kudos
SergeyKostrov
Valued Contributor II
783 Views
>>...smallest positive number = 2.22507e-308 In case of Double-Precision FP arithmetics this is an absolutely correct number. Take a look at 'float.h' for more information.
0 Kudos
Reply