# Some initial issues, variable types and long doubles treatment

## Some initial issues, variable types and long doubles treatment

Hello,

Do long doubles need a special treatment? Anyone know a reason why the would stop working properly?

I've recently started to migrate my project to Paralell Studio.
So far, the setup is ok, and I have sample projects up and running, that use Intel C++ compiler.
Now, I have problems with the main project. It is a DirectX 3d software, and it uses a wide set of libraries.
Program loads and starts and I can tell that it is running, however, it is not working as expected, because none of the objects are being positioned.

Since positions are stored in long double variable type, I was thinking that this could be related, as I see other posts about long doubles here in the forum.

It even fails with all the .cpp files using Microsoft compiler (while Intel C++ is still the project compiler, just used for linking).

So, once again, do long doubles need a special treatment?
Are there any other variable type with special treatment? (variable definitions, assignements, operations..)

www.mpl3d.com
28 posts / 0 new
For more complete information about compiler optimizations, see our Optimization Notice.

Hi,

Quoting mpl3dDo long doubles need a special treatment?..
Could you provide more technical details? A simple example of calculations that reproduces the problem
would be useful.

Best regards,
Sergey

As the other post indicates, it seems the support for long double as distinct from double may have been removed from Parallel Studio, and possibly from the most recent versions of ICL. This might have been done to follow Microsoft's lead.

Quoting TimP (Intel)As the other post indicates, it seems the support for long double as distinct from double may have been removed from Parallel Studio...
I think that the problem is possibly related to the Precision Control of aFloating Point Unit ( FPU ). Hereare
results ofa quick test I've done:

...
Sub-Test - long double
24-bit : [ 0.1 * 0.1 = 0.00999999977648258 ] <- 0.1*0.1!= 0.01
53-bit : [ 0.1 * 0.1 = 0.01000000000000000 ]
64-bit : [ 0.1 * 0.1 = 0.01000000000000000 ]
Default : [ 0.1 * 0.1 = 0.01000000000000000 ]
...

You can see as soon as a 24-bit precision is set by a '_control87'functionaccuracy of calculations drops.

Aprecision changecould be possiblydone by some library the user 'mpl3d' uses.

Recent icc and icl used -[Q]pc80 to reset precision mode to 64-bit. That option worked together with /Qlong-double. Microsoft libraries never supported 64-bit precision mode.

Quoting TimP (Intel)Recent icc and icl used -[Q]pc80 to reset precision mode to 64-bit.That option worked together with /Qlong-double. Microsoft libraries never supported 64-bit precision mode.

Since'sizeof( long double )' equals to 8 with Microsoft C/C++ compiler how couldthey supportthe 64-bit
precision? Even a ~20-year old Turbo C++ compiler supports it because in its case 'sizeof( long double )' equals to 10.

Hello, many thanks for all your tips.
I'm afraid I have not been able to isolate the problem yet.

The project uses a lot of different stuff, and it seems that it is getting some sort of dead lock when checking start-up conditions.

Regarding the FPU settings I do need to set it like this

#pragma fenv_access (on)
unsigned int cw = _control87(0, 0);
_clear87();
_control87(0x00000000, 0x00030000);

It marks a difference here with the Microsoft compiler. When not set, I do encounter float jerkyness in some scenarios.

I thought that would give me 80-bit precision, but later I found that it could be giving only 53-bit.
It is true that the documentation is a little bit misleading (at least it is to me, specially regarding fenv_access). Here are some links:

In any case, I would need to set this for the Intel compiler too. Should I understand by your comments that this is deprecated?
Many thanks.

www.mpl3d.com

Quoting mpl3d

Hello, many thanks for all your tips.
I'm afraid I have not been able to isolate the problem yet.

The project uses a lot of different stuff, and it seems that it is getting some sort of dead lock when checking start-up conditions.

Regarding the FPU settings I do need to set it like this

#pragma fenv_access (on)
unsigned int cw = _control87(0, 0);
_clear87();
_control87(0x00000000, 0x00030000);

It marks a difference here with the Microsoft compiler. When not set, I do encounter float jerkyness in some scenarios...

Could you give some example? It really impossible toguess what is going on in some of your scenarios
without a solid example. Also, what libraries do you use?

Quoting mpl3d...Regarding the FPU settings I do need to set it like this

#pragma fenv_access (on)
unsigned int cw = _control87(0, 0);
_clear87();
_control87(0x00000000, 0x00030000);
...

Yes, it will work. However, you have to be very carefull when using constants in '_control87' functioninstead macros
defined in 'float.h' header file. It will work for Microsoft, Intel and MinGW C++ compilers, and it won't work for Borland and
Turbo C++ compilers. A better versionlooks like:

...
_control87( _CW_DEFAULT, _MCW_PC );
...

Using a_PC_64 macrois useless when sizeof( long double ) is equal to 8. It won't make a precision of FP-calculations better and
is actually the same as if you woulduse a_PC_53 macro.

Quoting mpl3d ...
_control87(0x00000000, 0x00030000);
...

Here is a piece of codes from 'float.h' header file:

```...

#define _MCW_PC         0x00030000              /* Precision Control */

#define _PC_64          0x00000000              /*    64 bits */

#define _PC_53          0x00010000              /*    53 bits */

#define _PC_24          0x00020000              /*    24 bits */

...
...

#define DBL_DIG         15                      /* # of decimal digits of precision */

#define DBL_EPSILON     2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */

#define DBL_MANT_DIG    53                      /* # of bits in mantissa */

#define DBL_MAX         1.7976931348623158e+308 /* max value */

#define DBL_MAX_10_EXP  308                     /* max decimal exponent */

#define DBL_MAX_EXP     1024                    /* max binary exponent */

#define DBL_MIN         2.2250738585072014e-308 /* min positive value */

#define DBL_MIN_10_EXP  (-307)                  /* min decimal exponent */

#define DBL_MIN_EXP     (-1021)                 /* min binary exponent */

#define _DBL_ROUNDS     1                       /* addition rounding: near */

...

#define LDBL_DIG        DBL_DIG                 /* # of decimal digits of precision */

#define LDBL_EPSILON    DBL_EPSILON             /* smallest such that 1.0+LDBL_EPSILON != 1.0 */

#define LDBL_MANT_DIG   DBL_MANT_DIG            /* # of bits in mantissa */

#define LDBL_MAX        DBL_MAX                 /* max value */

#define LDBL_MAX_10_EXP DBL_MAX_10_EXP          /* max decimal exponent */

#define LDBL_MAX_EXP    DBL_MAX_EXP             /* max binary exponent */

#define LDBL_MIN        DBL_MIN                 /* min positive value */

#define LDBL_MIN_10_EXP DBL_MIN_10_EXP          /* min decimal exponent */

#define LDBL_MIN_EXP    DBL_MIN_EXP             /* min binary exponent */

#define _LDBL_ROUNDS    DBL_ROUNDS              /* addition rounding: near */

...

```
Asyou canseeall LDBL_* macrosbased on DBL_* macros.

Quoting mpl3d...
_control87(0x00000000, 0x00030000);
...

In case of a portable software I recommend to isolate as many as possible macros from 'float.h' header file.
Here is an example how it could be done:

```...

For Microsoft ( Desktop & CE ) & Intel C++ compilers
#if ( defined ( _WIN32_MSC ) || defined ( _WIN32CE_MSC ) || defined ( _WIN32_ICC ) )
#define _RTFPU_MCW_PC					MCW_PC

#define _RTFPU_CW_DEFAULT				_CW_DEFAULT

#define _RTFPU_CW_ALLBITSON				0xFFFFF
#define _RTFPU_MCW_EM					_MCW_EM

...

#define _RTFPU_PC_53					_PC_53

#define _RTFPU_CW_PC53_RCNEAR			( _PC_53+_RC_NEAR+_EM_INVALID+_EM_ZERODIVIDE+_EM_OVERFLOW+... )

...

#define _RTFPU_EM_INEXACT				_EM_INEXACT			// 0x00000001

#define _RTFPU_EM_ZERODIVIDE			_EM_ZERODIVIDE		// 0x00000008
#endif
For MinGW C++ compiler
#if defined ( _WIN32_MGW )
#define _RTFPU_MCW_PC					_MCW_PC

#define _RTFPU_CW_DEFAULT				( _PC_53+_RC_NEAR+_EM_INVALID+_EM_ZERODIVIDE+_EM_OVERFLOW+... )

#define _RTFPU_CW_ALLBITSON				0xFFFFF
#define _RTFPU_MCW_EM					_MCW_EM

...

#define _RTFPU_PC_53					_PC_53

#define _RTFPU_CW_PC53_RCNEAR			( _PC_53+_RC_NEAR+_EM_INVALID+_EM_ZERODIVIDE+_EM_OVERFLOW+... )

...

#define _RTFPU_EM_INEXACT				_EM_INEXACT			// 0x00000001

#define _RTFPU_EM_ZERODIVIDE			_EM_ZERODIVIDE		// 0x00000008
#endif
For Borland C++ compiler
#if defined ( _WIN32_BCC )
#define _RTFPU_MCW_PC					MCW_PC

#define _RTFPU_CW_DEFAULT				CW_DEFAULT

#define _RTFPU_CW_ALLBITSON				0xFFFFF
#define _RTFPU_MCW_EM					MCW_EM

...

#define _RTFPU_PC_53					PC_53

#define _RTFPU_CW_PC53_RCNEAR			(  PC_53+ RC_NEAR+ EM_INVALID+ EM_ZERODIVIDE+ EM_OVERFLOW+... )

...

#define _RTFPU_EM_INEXACT				EM_INEXACT			// 0x00000020

#define _RTFPU_EM_ZERODIVIDE			EM_ZERODIVIDE		// 0x00000004
#endif
For Turbo C++ compiler
#if defined ( _COS16_TCC )
#define _RTFPU_MCW_PC					MCW_PC

#define _RTFPU_CW_DEFAULT				CW_DEFAULT

#define _RTFPU_CW_ALLBITSON				0xFFFF
#define _RTFPU_MCW_EM					MCW_EM

...

#define _RTFPU_PC_53					PC_53

#define _RTFPU_CW_PC53_RCNEAR			(  PC_53+ RC_NEAR+ EM_INVALID+ EM_ZERODIVIDE+ EM_OVERFLOW+... )

...

#define _RTFPU_EM_INEXACT				EM_INEXACT			// 0x00000020

#define _RTFPU_EM_ZERODIVIDE			EM_ZERODIVIDE		// 0x00000004
#endif

...
Can you see that values for some macros, like EM_INEXACT or EM_ZERODIVIDE, different?
```

Quoting mpl3d...
unsigned int cw = _control87(0, 0);
...

Regarding a Default state of FPU.Here is example ofDefault states of FPU:

// Microsoft & Intel C++ compilers ( Visual Studio 20xx )
Default: 0x9001F
0.1 * 0.1 = 1.000000000000000e-002

// Microsoft C++ compiler ( Visual Studio 98 )
Default: 0x9001F
0.1 * 0.1 = 1.000000000000000e-002

// MinGW C++ compiler
Default: 0x9001F
0.1 * 0.1 = 1.000000000000000e-002

// Borland C++ compiler
Default: 0x1372
0.1 * 0.1 = 1.000000000000000e-02

// Turbo C++ compiler
Default: 0x1372
0.1 * 0.1 = 1.000000000000000e-02

Remember, thata differentstate ofFPU could create inconsistencies and this is what you have at the moment.

@Sergey, many thanks for all your posts.

They certainly clarify my initial confusion with the Intel C++ compiler regarding float treatment.

I'm sorry that I've not been able to isolate the issue yet.

Full code is 150k lines, and start-up might take something like 5k-10k lines, and I have not had the time to debug these lines.

It seems that, at some point during start-up, a comparison involving floats is not being succesful (although it is in the Microsoft compiler), and therefore the code flow doesn't enter to create some crucial stuff. I'll find out which is the problematic function/operation and I'll let you know.

Many thanks.

www.mpl3d.com

Quoting mpl3d...
I'm sorry that I've not been able to isolate the issue yet.

Full code is 150k lines, and start-up might take something like 5k-10k lines, and I have not had the time to debug these lines...

Hi,

Is there any progress with investigation?

Best regards,
Sergey

Sergey,

Many thanks for your interest, I see that you stay tuned.
No further investigation yet (no time).
I'll post any conclusion and I'll let you know, I'm sorry that I'm too much overloaded.

Best regards,
Manuel

www.mpl3d.com

I had the time to test today but the trial has expired.

Last thing I was able to find out is that the math functions that I use were returning 0.

These are in a static .lib library, and they pretty much wrap the native DX math functions that work with 3d vectors.

I was isolating the issue and playing with the float related compiler options, and then it compiled no more.

Oh well, I'll try to set it up in a different machine one of these days. Sorry by now.

www.mpl3d.com

Quoting mpl3d...Last thing I was able to find out is that the math functions that I use were returning 0.

These are in a static .lib library, and they pretty much wrap the native DX math functions that work with 3d vectors...
Could you provide more technical details ( headers, sources )?

@Sergey,

These are the function prototypes:

////////////////////////////////////////

bool dbMakeVector3 ( int iID );
bool dbDeleteVector3 ( int iID );
void dbSetVector3 ( int iID, float fX, float fY, float fZ );
float dbXVector3 ( int iID );
float dbYVector3 ( int iID );
float dbZVector3 ( int iID );
////////////////////////////////////////

And I'm testing like this:

////////////////////////////////////////
float test_valueX = 0.0f;
float test_valueY = 0.0f;
float test_valueZ = 0.0f;

//Use math funcions
dbMakeVector3 ( 1 ); //Create vector 3
dbSetVector3 ( 1, 1.0f, 2.0f, 3.0f); //Set vector components

//Debug
test_valueX = dbXVector3 ( 1 ); //Recover component X value
test_valueY = dbYVector3 ( 1 ); //Recover component Y value
test_valueZ = dbZVector3 ( 1 ); //Recover component Z value
////////////////////////////////////////

I was going to pack a VS2008 sample project, but then I realized that DirectX SDK (August 2007) must be installed to be able to compile, and I don't want to bother you that far.

However, I've uploaded the library '3DMaths.lib' here, perhaps you would like to inspect it:

Also comment that Intel Development Support is helping me out to expand the trial period, so hopefully I'll be able to be back on this issue soon.
Also, they pointed me to this link:

http://software.intel.com/en-us/articles/consistency-of-floating-point-results-using-the-intel-compiler/

Looking forward to know if finally those static libraries still can be used with the Intel C++ compiler. I'm very interested to test parallel performance on my application. Now this time I won't let the trial expire again, sorry for that.

Many thanks all along.
Best regards,
Manuel

www.mpl3d.com

Hi Manuel,

Quoting mpl3d...I was going to pack a VS2008 sample project, but then I realized that DirectX SDK (August 2007) must be installed to be able to compile, and I don't want to bother you that far...
I have DirectX SDK (June 2007) installed on one of my computers.

So, if you make aVisual Studio 2005 or 2008 testproject I'll be able to look at it. Please don't over-complicatethe test project
because there is a two-month difference between DirectX SDKs. I also take a look at libraries you've attached.

Best regards,
Sergey

Hi Sergey,

I've posted a link to a sample project in a private post, since it is not my aim to distribute such libraries.

Best regards,
Manuel

www.mpl3d.com

Quoting mpl3d...However, I've uploaded the library '3DMaths.lib' here, perhaps you would like to inspect it:

Also comment that Intel Development Support is helping me out to expand the trial period, so hopefully I'll be able to be back on this issue soon.
Also, they pointed me to this link:

[SergeyK] I know that article and I would rate it as 'One Of The Best'.

Quoting Sergey KostrovQuoting mpl3d...However, I've uploaded the library '3DMaths.lib' here, perhaps you would like to inspect it:

Here is a Summary:

It looks like another library is needed because 3DMaths.lib uses 2 external functions and one external structure:

IDirect3DDevice9 * __cdecl dbGetDirect3DDevice(void)
void * __cdecl dbGetCameraInternalData(int)
struct GlobStruct * g_pGlob

Here is a Compilation Report ( with MS C++ compiler of VS 2005 ):

------ Build started: Project: 3DMathsTestApp, Configuration: Release Win32 ------
Compiling...
3DMathsTestApp.cpp
3DMaths.lib(cVectorC.obj) : error LNK2001: unresolved external symbol "struct IDirect3DDevice9 * __cdecl dbGetDirect3DDevice(void)" (?dbGetDirect3DDevice@@YAPAUIDirect3DDevice9@@XZ)
3DMaths.lib(cVectorC.obj) : error LNK2001: unresolved external symbol "void * __cdecl dbGetCameraInternalData(int)" (?dbGetCameraInternalData@@YAPAXH@Z)
3DMaths.lib(CError.obj) : error LNK2001: unresolved external symbol "struct GlobStruct * g_pGlob" (?g_pGlob@@3PAUGlobStruct@@A)
C:\WorkEnv.Test\3DMathsTestApp\Release\3DMathsTestApp.exe : fatal error LNK1120: 3 unresolved externals
3DMathsTestApp - 4 error(s), 0 warning(s)

------ Build started: Project: 3DMathsTestApp, Configuration: Debug Win32 ------
Compiling...
3DMathsTestApp.cpp
3DMaths.lib(cVectorC.obj) : error LNK2019: unresolved external symbol "struct IDirect3DDevice9 * __cdecl dbGetDirect3DDevice(void)" (?dbGetDirect3DDevice@@YAPAUIDirect3DDevice9@@XZ) referenced in function "void __cdecl Constructor(struct HINSTANCE__ *)" (?Constructor@@YAXPAUHINSTANCE__@@@Z)
3DMaths.lib(cVectorC.obj) : error LNK2019: unresolved external symbol "void * __cdecl dbGetCameraInternalData(int)" (?dbGetCameraInternalData@@YAPAXH@Z) referenced in function "void __cdecl PassCoreData(void *)" (?PassCoreData@@YAXPAX@Z)
3DMaths.lib(CError.obj) : error LNK2019: unresolved external symbol "struct GlobStruct * g_pGlob" (?g_pGlob@@3PAUGlobStruct@@A) referenced in function "void __cdecl RunTimeError(unsigned long,char *)" (?RunTimeError@@YAXKPAD@Z)
C:\WorkEnv.Test\3DMathsTestApp\Debug\3DMathsTestApp.exe : fatal error LNK1120: 3 unresolved externals
3DMathsTestApp - 4 error(s), 0 warning(s)

========== Build: 0 succeeded, 2 failed, 0 up-to-date, 0 skipped ==========

Here is aVS 2005test project:'3DMathsTestApp.zip'( attached ).

## Attachments:

AttachmentSize
44.89 KB

Hi Sergey,

The file was verified. Sorry for the inconveniences.
I've uploaded it again in .zip format, please check the private post.

Those unresolved are from other .lib files, Camera.lib, Display.lib, and so on.
I think it is not possible to use 3DMaths.lib without them, and as soon these are included, they generate new dependencies.
Please use the full libraries (all of them) in the new .zip file.

Also, no need to try debug configuration. I think these libs are only for release mode.

Nevertheless, the project code that you attached looks fine to me for a test.
You know, just put the folders in the .zip file at the corresponding VS paths for includes and libs and you should be done.

However, I think that if you use VS2005 / DX SDK June 2007, we could find new compiling issues.
Just please let me know if any.

Many thanks,
Manuel

www.mpl3d.com

Quoting mpl3d...Those unresolved are from other .lib files, Camera.lib, Display.lib, and so on.
I think
it is not possible to use 3DMaths.lib without them, and as soon these are included, they generate new dependencies.
Please use the full libraries (all of them) in the new .zip file...

Yes, I confirm that.I tried to usealinker option /FORCE and itdoesn't forceall unresolved references to be resolved.
I used all libraries thatyou've provided.

Best regards,
Sergey

Zip-archive with latestsources attached. You can useVisual Studio 2005 ( Pro )or 2008 ( Pro / Express )now.

Best regards,
Sergey

## Attachments:

AttachmentSize
6.76 KB

Thanks Segey,

I expected something like:

Vector Values: [ X=0.000000 Y=0.000000 Z=0.000000 ]

That is, these kind of functions were returning 0.0 in the main project. That was the latest identified problem.
So it seems that at least these functions are working fine in an isolated test.

I can't test your project now, but I'll check it out when I arrive to my office.

I think I'll reinstall Parallel Studio in my laptop so I can continue testing (no news so far from Intel Development Support).

Best regards,
Manuel

www.mpl3d.com

Quoting mpl3dI expected something like:

Vector Values: [ X=0.000000 Y=0.000000 Z=0.000000 ]

[SergeyK]I think there issome internal error(s) in the libraries.

Manuel,What C++ compilerdid you use tobuild the libraries?

I also commented out calls todbPrintand dbSuspendForKey functions. Take a look as soon as you have time:

```void _tmain( void )

{

#ifdef _DEBUG

TCHAR szConfiguration[] = _T("DEBUG");

#else

TCHAR szConfiguration[] = _T("RELEASE");

#endif
_tprintf( _T("Tests Started [ %s configuration ]n"), &szConfiguration[0] );
// Declare

float test_valueX = 0.0f;

float test_valueY = 0.0f;

float test_valueZ = 0.0f;
// Use math funcions

dbMakeVector3( 1 );									// Create Vector3

dbSetVector3( 1, 1.0f, 2.0f, 3.0f );				// Set Vector3 components
// Verify

test_valueX = dbXVector3( 1 );						// Recover component X value of the Vector3

test_valueY = dbYVector3( 1 );						// Recover component Y value of the Vector3

test_valueZ = dbZVector3( 1 );						// Recover component Z value of the Vector3
_tprintf( _T("Vector Values: [ X=%f Y=%f Z=%f ]n"), test_valueX, test_valueY, test_valueZ );
// Print Vector3 values

//	dbPrint( ( double )test_valueX );					// Doesn't display value ( commented out )

//	dbPrint( ( double )test_valueY );					// Doesn't display value ( commented out )

//	dbPrint( ( double )test_valueZ );					// Doesn't display value ( commented out )
_tprintf( _T("Tests Completedn") );
// Press any key

//	dbSuspendForKey();									// Something is wrong ( commented out )

}
```