- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The default behavior is to use a fast but aproximate division in Fortran. What flag sets this feature to the most accurate division?
Is it possible to set this flag on a unit by unit basis?
Is it possible to set this flag on a unit by unit basis?
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I might add that we did get a very significant reduction in noise by setting result variables to 0.0d0 before calculations as below, but we have one algorithm that needs to be much more consistent.
FUNCTION div(a, b) RESULT(c)
REAL(8), INTENT(IN) :: a, b
REAL(8) :: c
c = 0.0d0
c = a / b
END FUNCTION div
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try /fp:precise You can specify this on a source by source basis.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Matt,
The compiler optimizations (assuming you do optimize) should eliminate the "c = 0.0d0" in the above example.
Assuming something else is inserted there that is not optimized out. The something else could coerce the rounding of 0.5 bit to always be in one direction (as opposed to in a random direction).
The "stability" you observe may come at the expense of accuracy of the overall approximation.
Jim
The compiler optimizations (assuming you do optimize) should eliminate the "c = 0.0d0" in the above example.
Assuming something else is inserted there that is not optimized out. The something else could coerce the rounding of 0.5 bit to always be in one direction (as opposed to in a random direction).
The "stability" you observe may come at the expense of accuracy of the overall approximation.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With IFort, by default optimization is turned on. Your function, compiled for X64, gives exactly three instructions:
I do not understand what you mean by "noise" in a non-physical context. If the introduction of do-nothing statements is causing a change to the significant results of a calculation, I suspect that there are bugs in the algorithm or the implementation.
[bash]0000000000000000On IA-32, likewise:: 0: f2 0f 10 07 movsd (%rdi),%xmm0 # load a
4: f2 0f 5e 06 divsd (%rsi),%xmm0 # divide by b
8: c3 retq [/bash]
[bash]00000000Thus, your assignment c = 0.0d0 has been removed by the optimizer, and its presence in the source code should have no effect on results.: 0: 83 ec 08 sub $0x8,%esp 3: 8b 44 24 0c mov 0xc(%esp),%eax 7: 8b 54 24 10 mov 0x10(%esp),%edx b: f2 0f 10 00 movsd (%eax),%xmm0 # load a
f: f2 0f 5e 02 divsd (%edx),%xmm0 # divide by b
13: f2 0f 11 04 24 movsd %xmm0,(%esp) 18: dd 04 24 fldl (%esp) 1b: 83 c4 08 add $0x8,%esp 1e: c3 ret
[/bash]
I do not understand what you mean by "noise" in a non-physical context. If the introduction of do-nothing statements is causing a change to the significant results of a calculation, I suspect that there are bugs in the algorithm or the implementation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/Qprec-div prevents the compiler from using an iterative sequence to increase throughput for division. The iterative sequence has unpredictable rounding, affecting the last bit of precision, and may fail (produce NaN or 0.) when dividing operands of very large or small magnitude. Normally, that non-IEEE accurate sequence would be used only for single precision vectorization.
/Qprec-sqrt prevents the analogous iteration for sequences involving sqrt() or 1/sqrt().
Those /Qprec- options are included in /fp:source and similar options, as Steve mentioned.
The usual way of changing these flags among units of a build is by Makefile or splitting projects.
As the less consistent method tends to be associated with vectorization, it should be possible to get the IEEE accurate result at the expense of performance by employing !dir$ no vector directives for vectorizable loops containing division, but I couldn't recommend that, as the IEEE accurate /Qprec-div vectorization normally performs well with all CPUs in current production.
/Qprec-sqrt prevents the analogous iteration for sequences involving sqrt() or 1/sqrt().
Those /Qprec- options are included in /fp:source and similar options, as Steve mentioned.
The usual way of changing these flags among units of a build is by Makefile or splitting projects.
As the less consistent method tends to be associated with vectorization, it should be possible to get the IEEE accurate result at the expense of performance by employing !dir$ no vector directives for vectorizable loops containing division, but I couldn't recommend that, as the IEEE accurate /Qprec-div vectorization normally performs well with all CPUs in current production.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page