Similarly, rounding modes are saved and restored for procedures.
Fortran has an optional IEEE module. One of its important features
is that flags (IEEE exceptions) are set to quiet on entry of a procedure
and restored to signalling if it was signalling on entry, or keep it signalling if it was raised on in the procedure. Similarly, rounding
modes are saved and restored for procedures. This is automatically
done if the right IEEE modules are used. A user can set rounding
modes or set and clear exceptions using the right modes.
Conceptually, this is the right thing to do. A library routine should
not produce different results depending on what a user did for his
own calculations.
Computationally, this can be quite expensive
- having the meaning
of a calculation changed by changing FP state should (I hope so,
for corecntess's sake) flush any calculations done with the wrong
FP mode. Just calling a small library routine which does so could
be enough.
An example of the high cost is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570 where, depending
on the library implementation, gfortran may be over-cautious
for the ieee_next_after function by saving and restoring fp state,
but I'm not sure that the overhead is actually from the FP state or
from calling extra functions.
So... What is the best way to do allow this to be more efficient?
The CPU could speculate on the FP mode (not sure if that is actually
done). Other suggestions? How do current CPUs do so?
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
2. Does above said mean that caller has no way of modifying rounding
mode used by callee? If true, it defeats one of original reasons for
which Kahan invented rounding modes in the first place.
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
2. Does above said mean that caller has no way of modifying rounding
mode used by callee? If true, it defeats one of original reasons for
which Kahan invented rounding modes in the first place.
The caller cannot change the callee's rounding mode without the
callee having been designed for this (by taking the rounding mode
as an extra argument and using IEEE_SET_ROUNDING_MODE itself).
I think that's a good idea. If a library routine is written
and debugged for a particular rounding mode, results should
not change because somebody up the call tree changed it.
Thomas Koenig <[email protected]> posted:
Fortran has an optional IEEE module. One of its important features
is that flags (IEEE exceptions) are set to quiet on entry of a
procedure and restored to signalling if it was signalling on entry,
or keep it signalling if it was raised on in the procedure.
Similarly, rounding modes are saved and restored for procedures.
This is automatically done if the right IEEE modules are used. A
user can set rounding modes or set and clear exceptions using the
right modes.
How does a user set up his environment such that if TAN()* overflows
to infinity it returns with the OVERFLOW flag set ?!?
(*) EXP(), POW(,)
Conversely, how does one write a TAN()* subroutine with the above
property ?
Conceptually, this is the right thing to do. A library routine
should not produce different results depending on what a user did
for his own calculations.
I would think that a user setting RM=ToZero would WANT a different
result from SIN() than the same call with RM=RNE ?!?
Computationally, this can be quite expensive
And contrary to how IEEE 754 has been used for 40 years.
- having the meaning
of a calculation changed by changing FP state should (I hope so,
for corecntess's sake) flush any calculations done with the wrong
FP mode. Just calling a small library routine which does so could
be enough.
Oh, and BTW, how does a user CALL a subroutine to set his RM when
the RETURN undoes the very nature of his request ?!?
An example of the high cost is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570 where, depending
on the library implementation, gfortran may be over-cautious
for the ieee_next_after function by saving and restoring fp state,
but I'm not sure that the overhead is actually from the FP state or
from calling extra functions.
So... What is the best way to do allow this to be more efficient?
UN DO this change to IEEE 754.
The CPU could speculate on the FP mode (not sure if that is actually
done). Other suggestions? How do current CPUs do so?
Multi-threaded cores already have to ship different RMs to FUs on
each FP instruction. The HW is all there--its the ISAs that are
screwed up.
Thomas Koenig <[email protected]> posted:
Fortran has an optional IEEE module. One of its important features
is that flags (IEEE exceptions) are set to quiet on entry of a procedure
and restored to signalling if it was signalling on entry, or keep it
signalling if it was raised on in the procedure. Similarly, rounding
modes are saved and restored for procedures. This is automatically
done if the right IEEE modules are used. A user can set rounding
modes or set and clear exceptions using the right modes.
How does a user set up his environment such that if TAN()* overflows
to infinity it returns with the OVERFLOW flag set ?!?
(*) EXP(), POW(,)
Conversely, how does one write a TAN()* subroutine with the above property ?
Conceptually, this is the right thing to do. A library routine should
not produce different results depending on what a user did for his
own calculations.
I would think that a user setting RM=ToZero would WANT a different
result from SIN() than the same call with RM=RNE ?!?
Oh, and BTW, how does a user CALL a subroutine to set his RM when
the RETURN undoes the very nature of his request ?!?
An example of the high cost is
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570 where, depending
on the library implementation, gfortran may be over-cautious
for the ieee_next_after function by saving and restoring fp state,
but I'm not sure that the overhead is actually from the FP state or
from calling extra functions.
So... What is the best way to do allow this to be more efficient?
UN DO this change to IEEE 754.
The CPU could speculate on the FP mode (not sure if that is actually
done). Other suggestions? How do current CPUs do so?
Multi-threaded cores already have to ship different RMs to FUs on
each FP instruction. The HW is all there--its the ISAs that are screwed
up.
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
Michael S <[email protected]> schrieb:
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for
procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
OOOPS.
Seems I misread the standard, missing out on clause 17.4 paragraph 5,
which states
In a procedure other than IEEE_SET_ROUNDING_MODE or IEEE_SET_STATUS,
the processor shall not change the rounding modes on entry, and
on return shall ensure that the rounding modes are the same as
they were on entry.
So, that part of my premise was wrong. Sorry.
MitchAlsup <[email protected]d> schrieb:
Thomas Koenig <[email protected]> posted:
The CPU could speculate on the FP mode (not sure if that is actuallyMulti-threaded cores already have to ship different RMs to FUs on
done). Other suggestions? How do current CPUs do so?
each FP instruction. The HW is all there--its the ISAs that are screwed
up.
And that would be an interesting part - how to specify this
efficiently, and allow the microarchiteture not to flush when
rounding modes are changed.
Fortran has an optional IEEE module. One of its important features
is that flags (IEEE exceptions) are set to quiet on entry of a procedure
and restored to signalling if it was signalling on entry, or keep it signalling if it was raised on in the procedure. Similarly, rounding
modes are saved and restored for procedures. This is automatically
done if the right IEEE modules are used. A user can set rounding
modes or set and clear exceptions using the right modes.
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
2. Does above said mean that caller has no way of modifying rounding
mode used by callee? If true, it defeats one of original reasons for
which Kahan invented rounding modes in the first place.
The caller cannot change the callee's rounding mode without the
callee having been designed for this (by taking the rounding mode
as an extra argument and using IEEE_SET_ROUNDING_MODE itself).
I think that's a good idea. If a library routine is written
and debugged for a particular rounding mode, results should
not change because somebody up the call tree changed it.
Personally, I never found the whole rounding modes business useful in
my practice. So, can not say with straight face whether Fortran's take
on it is good idea or not. But I can say with good level of certainty
that William Kahan meant something else.
Michael S <[email protected]> schrieb:
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
OOOPS.
Seems I misread the standard, missing out on clause 17.4 paragraph 5,
which states
In a procedure other than IEEE_SET_ROUNDING_MODE or IEEE_SET_STATUS,
the processor shall not change the rounding modes on entry, and
on return shall ensure that the rounding modes are the same as
they were on entry.
Personally, I never found the whole rounding modes business useful in my practice.
On Sun, 14 Sep 2025 10:52:10 +0300, Michael S wrote:
Personally, I never found the whole rounding modes business useful in myI remember one of Kahan’s writings suggesting it is useful for testing numeric stability: if your code gives results that differ only slightly in the four different rounding modes, then your calculations are *probably* stable; if the results vary a lot, then your calculations are *probably* unstable.
practice.
Lawrence D’Oliveiro [2025-09-15 02:31:04] wrote:
On Sun, 14 Sep 2025 10:52:10 +0300, Michael S wrote:
Personally, I never found the whole rounding modes business useful in my >>> practice.I remember one of Kahan’s writings suggesting it is useful for testing
numeric stability: if your code gives results that differ only slightly in >> the four different rounding modes, then your calculations are *probably*
stable; if the results vary a lot, then your calculations are *probably*
unstable.
IIUC you can get the same result by adding a bit a noise to your inputs
and compare the output.
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for
procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
OOOPS.
Seems I misread the standard, missing out on clause 17.4 paragraph
5, which states
In a procedure other than IEEE_SET_ROUNDING_MODE or IEEE_SET_STATUS,
the processor shall not change the rounding modes on entry, and
on return shall ensure that the rounding modes are the same as
they were on entry.
IIUC this means that user can not define routine like
'MY_SET_ROUNDING_MODE' and get desired effect (this probably can be
worked around using foreign function interface).
On Sun, 14 Sep 2025 16:22:33 -0000 (UTC)
[email protected] (Waldek Hebisch) wrote:
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for
procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
OOOPS.
Seems I misread the standard, missing out on clause 17.4 paragraph
5, which states
In a procedure other than IEEE_SET_ROUNDING_MODE or IEEE_SET_STATUS,
the processor shall not change the rounding modes on entry, and
on return shall ensure that the rounding modes are the same as
they were on entry.
IIUC this means that user can not define routine like
'MY_SET_ROUNDING_MODE' and get desired effect (this probably can be
worked around using foreign function interface).
I am not sure that I understood.
Do you want to say that user can not write routines that call IEEE_SET_ROUNDING_MODE ? I don't see anything in citation above that
suggests that.
Or do you mean something else?
On Sun, 14 Sep 2025 10:19:08 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sun, 14 Sep 2025 07:18:38 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Michael S <[email protected]> schrieb:
On Sat, 13 Sep 2025 14:55:58 -0000 (UTC)
Thomas Koenig <[email protected]> wrote:
Similarly, rounding modes are saved and restored for
procedures.
I am not sure that I understand.
1. Is Fortran's equivalent of C's fesetround() is considered a
languge primitive rather than procedure?
Fortran has intrinsic procedures (like SIN, MATMUL or CPU_TIME),
procedures from intrinsic modules, like COMPILER_OPTIONS
from ISO_FORTRAN_ENV, and user-defined procedures.
IEEE_SET_ROUNDING_MODE is a procedure from an intrinsic module
(but an optional one). It need not be an external function;
the compiler is free to do other things to implement it.
(Hope this answers your question)
OOOPS.
Seems I misread the standard, missing out on clause 17.4 paragraph 5,
which states
In a procedure other than IEEE_SET_ROUNDING_MODE or IEEE_SET_STATUS,
the processor shall not change the rounding modes on entry, and
on return shall ensure that the rounding modes are the same as
they were on entry.
So, that part of my premise was wrong. Sorry.
Now it sounds like matching Kahan's intentions.
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt >handlers could effect the FPU flags visible in userland.
BGB <[email protected]> writes:
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt
handlers could effect the FPU flags visible in userland.
Why on earth would you use floating point instructions
in an interrupt handler?
BGB <[email protected]> writes:
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt
handlers could effect the FPU flags visible in userland.
Why on earth would you use floating point instructions
in an interrupt handler?
On 9/16/2025 12:50 PM, Scott Lurndal wrote:
BGB <[email protected]> writes:
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt
handlers could effect the FPU flags visible in userland.
Why on earth would you use floating point instructions
in an interrupt handler?
I didn't go and track down which code was using FPU instructions, but >seemingly something was, in any case. I didn't see any particular reason
to forbid using the FPU inside of interrupt handlers (they are mostly
still plain C, differing mostly in that there are limited to the
operating in terms of the physical memory map).
But, in any case, using FP instructions in an interrupt handler
shouldn't leave state changes that are visible in userland.
BGB <[email protected]> writes:
On 9/16/2025 12:50 PM, Scott Lurndal wrote:
BGB <[email protected]> writes:
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt >>>> handlers could effect the FPU flags visible in userland.
Why on earth would you use floating point instructions
in an interrupt handler?
I didn't go and track down which code was using FPU instructions, but
seemingly something was, in any case. I didn't see any particular reason
to forbid using the FPU inside of interrupt handlers (they are mostly
still plain C, differing mostly in that there are limited to the
operating in terms of the physical memory map).
The standard reasoning for prohibiting floating point in the
kernel is to improve system call overhead by not saving floating
point registers until and unless there is a context switch (and
even then, x86 has features that allow the OS to forgo saving
the floating point registers if they weren't used in the last
scheduling quantum).
But, in any case, using FP instructions in an interrupt handler
shouldn't leave state changes that are visible in userland.
A well understood problem handled by all off the shelf operating
systems.
On 9/17/2025 8:57 AM, Scott Lurndal wrote:
BGB <[email protected]> writes:
On 9/16/2025 12:50 PM, Scott Lurndal wrote:
BGB <[email protected]> writes:
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt >>>> handlers could effect the FPU flags visible in userland.
Why on earth would you use floating point instructions
in an interrupt handler?
I didn't go and track down which code was using FPU instructions, but
seemingly something was, in any case. I didn't see any particular reason >> to forbid using the FPU inside of interrupt handlers (they are mostly
still plain C, differing mostly in that there are limited to the
operating in terms of the physical memory map).
The standard reasoning for prohibiting floating point in the
kernel is to improve system call overhead by not saving floating
point registers until and unless there is a context switch (and
even then, x86 has features that allow the OS to forgo saving
the floating point registers if they weren't used in the last
scheduling quantum).
In my case, this wasn't x86, and on my ISA the FPU stuff is done in
GPRs, which typically need to be saved/restored either way. Well, except when running RISC-V code, which effectively splits the register space in half (32+32 rather than 64).
The issue was that the FPSR is (now) aliased to SP(63:48), but there was only a single SP; and the CPU core handles interrupts by causing SP and
SSP to switch places in decode.
The likely more proper solution would have been to have another FPSR
aliased to SSP(63:48) which also re-routes; where as-is SSP is currently only a 48 bit register internally.
But, for now, easier was to disable the updates if inside an ISR.
This issue wouldn't have existed if still using GBR/GP for this, but GBR
has the disadvantage that it gets stomped whenever a reload occurs; so
it was either tweak the GBR reload mechanism to not stomp FPSR, or move
FPSR somewhere where it doesn't get stomped (the high bits of SP being
the most obvious choice).
BGB <[email protected]> posted:
On 9/17/2025 8:57 AM, Scott Lurndal wrote:
BGB <[email protected]> writes:
On 9/16/2025 12:50 PM, Scott Lurndal wrote:
BGB <[email protected]> writes:
On 9/14/2025 9:06 AM, Michael S wrote:
Also there was another related bug where FPU instructions in interrupt >>>>>> handlers could effect the FPU flags visible in userland.
Why on earth would you use floating point instructions
in an interrupt handler?
I didn't go and track down which code was using FPU instructions, but
seemingly something was, in any case. I didn't see any particular reason >>>> to forbid using the FPU inside of interrupt handlers (they are mostly
still plain C, differing mostly in that there are limited to the
operating in terms of the physical memory map).
The standard reasoning for prohibiting floating point in the
kernel is to improve system call overhead by not saving floating
point registers until and unless there is a context switch (and
even then, x86 has features that allow the OS to forgo saving
the floating point registers if they weren't used in the last
scheduling quantum).
In my case, this wasn't x86, and on my ISA the FPU stuff is done in
GPRs, which typically need to be saved/restored either way. Well, except
when running RISC-V code, which effectively splits the register space in
half (32+32 rather than 64).
The issue was that the FPSR is (now) aliased to SP(63:48), but there was
only a single SP; and the CPU core handles interrupts by causing SP and
SSP to switch places in decode.
Switching SP with SSP does not work (fundamentally) when there are
4 privilege levels--as each privilege level needs its own unique SP.
The likely more proper solution would have been to have another FPSR
aliased to SSP(63:48) which also re-routes; where as-is SSP is currently
only a 48 bit register internally.
So, when one does a::
ADD SP,SP,#big-number
do the HoBs of SP get changed (like any other GPR or do you special
case SP ?!?
But, for now, easier was to disable the updates if inside an ISR.
My 66000 code does not even know it is in an ISR--as ISRs do not
disable interrupts, disable exceptions, and are re-entrant from
the very first ISR instruction.
Thus, ISRs can do FP if they desire, Vectorize loops as needed,
and are not limited in their use of ISA.
This issue wouldn't have existed if still using GBR/GP for this, but GBR
has the disadvantage that it gets stomped whenever a reload occurs; so
it was either tweak the GBR reload mechanism to not stomp FPSR, or move
FPSR somewhere where it doesn't get stomped (the high bits of SP being
the most obvious choice).
My ISA does not have this problem as it does not need a GBR, universal constants (this time as a displacement) eliminated the need.
Why on earth would you use floating point instructionsI didn't go and track down which code was using FPU instructions, but seemingly something was,
in an interrupt handler?
BGB <[email protected]> writes:
Why on earth would you use floating point instructionsI didn't go and track down which code was using FPU instructions, but
in an interrupt handler?
seemingly something was,
I believe I noted once before that I had to guide a driver developer for HP/UX away from using floating point for his driver's event counters. His reason for their use? They can count to bigger numbers.
Andy Valencia wrote:
BGB <[email protected]> writes:
Why on earth would you use floating point instructionsI didn't go and track down which code was using FPU instructions,
in an interrupt handler?
but seemingly something was,
I believe I noted once before that I had to guide a driver
developer for HP/UX away from using floating point for his driver's
event counters. His reason for their use? They can count to
bigger numbers.
Did you ask him what happened after the counter passed 2^53 and he
added 1.0 to the counter? With RNE that's a NOP...
Using 64-bit counters are far better, even on a 32-bit CPU, even if
you then need thread-safe/atomic code sequences.
Terje
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,071 |
Nodes: | 10 (0 / 10) |
Uptime: | 70:52:27 |
Calls: | 13,754 |
Calls today: | 1 |
Files: | 186,984 |
D/L today: |
11,494 files (3,339M bytes) |
Messages: | 2,425,734 |