Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #121694 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2025-02-24 11:48 +0100 |
| Last post | 2025-03-09 14:56 +0200 |
| Articles | 20 on this page of 134 — 8 participants |
Back to article view | Back to comp.lang.c++
a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 11:48 +0100
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 12:00 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 13:48 +0100
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 13:09 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 14:22 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 17:13 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 16:19 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 17:52 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 09:09 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 16:17 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-25 17:26 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 16:45 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 16:57 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-25 19:17 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 18:58 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-26 00:36 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-26 04:15 +0100
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-26 08:16 +0000
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-26 14:27 +0200
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-26 14:39 +0000
FP_CONTRACT was : a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-28 16:28 +0200
Re: FP_CONTRACT was : a MSVC and glibc-compatible fmod() Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-01 08:35 -0800
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 16:22 +0200
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 15:10 +0000
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 17:33 +0200
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 16:48 +0000
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-24 22:21 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 07:37 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-25 23:03 +0000
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-26 02:00 +0200
Re: a MSVC and glibc-compatible fmod() Wuns Haerst <Wuns.Haerst@wurstfabrik.at> - 2025-02-26 04:01 +0100
Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-25 08:24 +0000
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-27 21:16 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 07:59 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-28 12:35 +0200
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-28 18:12 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 19:23 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-28 18:30 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 19:31 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-28 19:47 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 20:49 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 14:37 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-01 16:58 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 17:11 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-01 21:02 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 20:32 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-01 21:37 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 20:45 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 09:40 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-01 22:55 +0200
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 18:54 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 17:59 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 15:41 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 17:10 +0100
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-02 16:22 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 17:26 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 19:07 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:09 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:11 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 19:52 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:55 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 20:09 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 19:14 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 19:57 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 22:58 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-03 12:52 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 18:10 +0200
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 23:55 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-07 09:51 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 18:20 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-03 17:30 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 19:27 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-03 18:39 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 02:01 +0200
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 19:37 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:41 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 20:00 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 19:01 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 01:31 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 07:41 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 11:08 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 10:31 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 11:46 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 10:54 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 12:09 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 11:21 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 14:09 +0200
Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-09 15:26 +0000
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 17:02 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 19:55 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 19:10 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 19:27 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 17:23 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 20:04 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 19:11 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 20:11 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 07:24 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 10:46 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 14:26 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 13:45 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 16:33 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 15:46 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 16:59 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 16:11 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 17:43 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 17:13 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 19:51 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 19:00 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 20:38 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 22:34 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 22:36 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 12:47 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 23:52 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 23:57 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 09:34 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 12:29 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 12:12 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 13:34 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 13:10 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 14:55 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 14:08 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 15:46 +0200
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 13:51 +0200
Re: a MSVC and glibc-compatible fmod() James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-03-11 14:21 -0400
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 20:28 +0200
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-16 13:48 +0200
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 13:17 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 12:53 +0100
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 12:54 +0100
Re: a MSVC and glibc-compatible fmod() wij <wyniijj5@gmail.com> - 2025-03-09 18:51 +0800
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 12:56 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 14:23 +0200
Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 13:39 +0100
Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 14:56 +0200
Page 1 of 7 [1] 2 3 4 5 6 7 Next page →
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-24 11:48 +0100 |
| Subject | a MSVC and glibc-compatible fmod() |
| Message-ID | <vphiom$11lsc$1@raubtier-asyl.eternal-september.org> |
I wanted to optimize fmod to be a bit faster. This is my C++20 solution.
double myFmod( double x, double y )
{
constexpr uint64_t
SIGN = 1ull << 63,
IMPLICIT = 1ull << 52,
MANT = IMPLICIT - 1,
QBIT = 1ull << 51;
uint64_t const
binX = bit_cast<uint64_t>( x ),
binY = bit_cast<uint64_t>( y );
static auto abs = []( uint64_t m ) { return m & ~SIGN; };
auto isNaN = []( uint64_t m ) { return abs( m ) >= 0x7FF0000000000001u; };
auto isSig = []( uint64_t m ) { return !(m & QBIT); };
if( isNaN( binX ) ) [[unlikely]] // x == NaN
#if defined(_MSC_VER)
return bit_cast<double>( isNaN( binY ) ? binY | binX & binY & QBIT :
binX );
#else
{
if( isSig( binX ) || isNaN( binY ) && isSig( binY ) ) [[unlikely]]
feraiseexcept( FE_INVALID );
return bit_cast<double>( binX | QBIT );
}
#endif
if( isNaN( binY ) ) [[unlikely]] // x != NaN || y == NaN
#if defined(_MSC_VER)
return y;
#else
{
if( isSig( binY ) ) [[unlikely]]
feraiseexcept( FE_INVALID );
return bit_cast<double>( binY | QBIT );
}
#endif
auto isInf = []( uint64_t m ) { return abs( m ) == 0x7FF0000000000000u; };
if( isInf( binX ) ) // x == Inf
{
feraiseexcept( FE_INVALID );
#if defined(_MSC_VER)
return bit_cast<double>( binX & ~MANT | QBIT );
#else
return -numeric_limits<double>::quiet_NaN();
#endif
}
if( !abs( binY ) ) [[unlikely]] // y == 0
{
feraiseexcept( FE_INVALID );
#if defined(_MSC_VER)
return numeric_limits<double>::quiet_NaN();
#else
return -numeric_limits<double>::quiet_NaN();
#endif
}
if( !abs( binX ) || isInf( binY ) ) [[unlikely]] // x == 0 || y == Inf
return x;
auto exp = []( uint64_t b ) -> int { return b >> 52 & 0x7FF; };
int
expX = exp( binX ),
expY = exp( binY );
auto mant = []( uint64_t b ) { return b & MANT; };
uint64_t
mantX = mant( binX ),
mantY = mant( binY );
static auto normalize = []( int &exp, uint64_t &mant )
{
unsigned shift = countl_zero( mant ) - 11;
mant <<= shift;
exp -= shift;
};
auto build = []( int &exp, uint64_t &mant )
{
if( exp ) [[likely]]
mant |= IMPLICIT;
else
{
exp = 1;
normalize( exp, mant );
}
};
build( expX, mantX );
build( expY, mantY );
uint64_t signX = binX & SIGN;
int expDiff;
while( (expDiff = expX - expY) > 0 )
{
unsigned bits = expDiff <= 11 ? expDiff : 11;
if( !(mantX = (mantX << bits) % mantY) ) [[unlikely]]
return bit_cast<double>( signX );
expX -= bits;
normalize( expX, mantX );
}
if( !expDiff && mantX >= mantY ) [[unlikely]]
if( (mantX -= mantY) ) [[likely]]
normalize( expX, mantX );
else
return bit_cast<double>( signX );
if( expX <= 0 ) [[unlikely]]
{
assert(expX >= -51);
mantX = mantX >> (unsigned)(-expX + 1);
expX = 0;
}
return bit_cast<double>( signX | (uint64_t)expX << 52 | mantX & MANT );
}
It's about six times faster than the glibc 2.31 solution in my
benchmark. The returned NaNs and the raised exceptions are MSVC-
and glibc-compatible.
[toc] | [next] | [standalone]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-02-24 12:00 +0000 |
| Message-ID | <vphn0u$12go8$1@dont-email.me> |
| In reply to | #121694 |
On Mon, 24 Feb 2025 11:48:08 +0100
Bonita Montero <Bonita.Montero@gmail.com> wibbled:
>I wanted to optimize fmod to be a bit faster. This is my C++20 solution.
>
>double myFmod( double x, double y )
[snip]
>
>It's about six times faster than the glibc 2.31 solution in my
>benchmark. The returned NaNs and the raised exceptions are MSVC-
>and glibc-compatible.
double myFmod(double x, double y)
{
double div = x / y;
return y * (div - (long)div);
}
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-24 13:48 +0100 |
| Message-ID | <vphppf$138sj$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121695 |
Am 24.02.2025 um 13:00 schrieb Muttley@DastardlyHQ.org:
> On Mon, 24 Feb 2025 11:48:08 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wibbled:
>> I wanted to optimize fmod to be a bit faster. This is my C++20 solution.
>>
>> double myFmod( double x, double y )
> [snip]
>>
>> It's about six times faster than the glibc 2.31 solution in my
>> benchmark. The returned NaNs and the raised exceptions are MSVC-
>> and glibc-compatible.
>
> double myFmod(double x, double y)
> {
> double div = x / y;
> return y * (div - (long)div);
> }
If the exponent difference between x and y is large enough this
returns results which are larger than y. glibc does it completley
with integer-operations also.
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-02-24 13:09 +0000 |
| Message-ID | <vphr2t$13ih6$1@dont-email.me> |
| In reply to | #121696 |
On Mon, 24 Feb 2025 13:48:02 +0100
Bonita Montero <Bonita.Montero@gmail.com> wibbled:
>Am 24.02.2025 um 13:00 schrieb Muttley@DastardlyHQ.org:
>> On Mon, 24 Feb 2025 11:48:08 +0100
>> Bonita Montero <Bonita.Montero@gmail.com> wibbled:
>>> I wanted to optimize fmod to be a bit faster. This is my C++20 solution.
>>>
>>> double myFmod( double x, double y )
>> [snip]
>>>
>>> It's about six times faster than the glibc 2.31 solution in my
>>> benchmark. The returned NaNs and the raised exceptions are MSVC-
>>> and glibc-compatible.
>>
>> double myFmod(double x, double y)
>> {
>> double div = x / y;
>> return y * (div - (long)div);
>> }
>
>If the exponent difference between x and y is large enough this
>returns results which are larger than y. glibc does it completley
>with integer-operations also.
If the values are so large or small that you start to get floating point
based errors then you should probably be using integer arthmetic or a large
number library anyway like GMP anyway.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-24 14:22 +0100 |
| Message-ID | <vphrpa$13lon$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121697 |
Am 24.02.2025 um 14:09 schrieb Muttley@DastardlyHQ.org: > If the values are so large or small that you start to get floating point > based errors then you should probably be using integer arthmetic or a large > number library anyway like GMP anyway. There's no need for large integer arithmetics since each calculation step results in a mantissa with equal or less bits than the divisor. Even if the exponents are close enough to have not missing integer -bits the following multiplication is very likely to have a precision -loss. All current solutions (MSVC, libstdc++) work with integer-ope- tations and are always 100% precise.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-24 17:13 +0200 |
| Message-ID | <20250224171343.000016aa@yahoo.com> |
| In reply to | #121698 |
On Mon, 24 Feb 2025 14:22:04 +0100 Bonita Montero <Bonita.Montero@gmail.com> wrote: > Am 24.02.2025 um 14:09 schrieb Muttley@DastardlyHQ.org: > > > If the values are so large or small that you start to get floating > > point based errors then you should probably be using integer > > arthmetic or a large number library anyway like GMP anyway. > > There's no need for large integer arithmetics since each calculation > step results in a mantissa with equal or less bits than the divisor. > Even if the exponents are close enough to have not missing integer > -bits the following multiplication is very likely to have a precision > -loss. All current solutions (MSVC, libstdc++) work with integer-ope- > tations and are always 100% precise. > > Do you have real application for fast fmod() or just playing? For as long as y is positive and abs(x/y) <= 2**53, a very simple formula will produce precise result: fma(trunc(x/fabs(y)), -fabs(y), x).
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-24 16:19 +0100 |
| Message-ID | <vpi2lk$1564p$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121701 |
Am 24.02.2025 um 16:13 schrieb Michael S: > Do you have real application for fast fmod() or just playing? I experimented with x87 FPREM and wanted to know whether it is precise; it isn't and the results can be > y. So I developed my own routine which is always 100% precise. > For as long as y is positive and abs(x/y) <= 2**53, a very simple > formula will produce precise result: fma(trunc(x/fabs(y)), -fabs(y), x). The multiplication mostly will drop bits so that the difference might become larger than y.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-24 17:52 +0200 |
| Message-ID | <20250224175258.00002799@yahoo.com> |
| In reply to | #121702 |
On Mon, 24 Feb 2025 16:19:35 +0100 Bonita Montero <Bonita.Montero@gmail.com> wrote: > Am 24.02.2025 um 16:13 schrieb Michael S: > > > Do you have real application for fast fmod() or just playing? > > I experimented with x87 FPREM and wanted to know whether it is > precise; it isn't That is not surprising. It wouldn't be called *partial* reminder otherwise. > and the results can be > y. That's a little unexpected, but mentioned in the Intel and AMD manuals. It can happen when abs(x/y) > 2**32. If you think about how FPREM works, you'd realize that for abs(x/y) > 2**63 it is a necessity. Still rem(x,y) == rem(fprem(x,y), y), so this unusual property does not prevent FPREM from getting correct answer when we run it in loop. But in the worst case loop can take something like 1000 iterations :( > So I developed my own > routine which is always 100% precise. > > > For as long as y is positive Actually, formula appears to work for negative y as well. > and abs(x/y) <= 2**53, a very simple > > formula will produce precise result: fma(trunc(x/fabs(y)), > > -fabs(y), x). > > The multiplication mostly will drop bits so that the difference might > become larger than y. > That is why I don't use multiplication. Did you ever asked yourself what is the meaning of 'f' in 'fma' ?
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-25 09:09 +0100 |
| Message-ID | <vpjtrg$1r7bj$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121704 |
Am 24.02.2025 um 16:52 schrieb Michael S:
> That is why I don't use multiplication. Did you ever asked yourself
> what is the meaning of 'f' in 'fma' ?
The FMA-instructions produce the same results:
#include <iostream>
#include <random>
#include <bit>
#include <cmath>
#include <iomanip>
#include <intrin.h>
using namespace std;
int main()
{
auto fma = []( double a, double b, double c )
{
__m128d mA, mB, mC;
mA.m128d_f64[0] = a;
mB.m128d_f64[0] = b;
mC.m128d_f64[0] = c;
return _mm_fmadd_pd( mA, mB, mC ).m128d_f64[0];
};
mt19937_64 mt;
uniform_int_distribution<uint64_t> finites( 1, 0x7FEFFFFFFFFFFFFFu );
auto rnd = [&]() -> double { return bit_cast<double>( finites( mt ) ); };
ptrdiff_t nEQs = 0;
for( ptrdiff_t r = 0; r != 1'000'000; ++r )
{
double
a = rnd(), b = rnd(), c = rnd(),
rA = fma( a, b, c ),
rB = a * b + c;
nEQs = rA != rB;
}
cout << hexfloat << nEQs / 1.0e6 << endl;
}
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-25 16:17 +0100 |
| Message-ID | <vpkmu2$21pje$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121708 |
Am 25.02.2025 um 09:09 schrieb Bonita Montero:
> Am 24.02.2025 um 16:52 schrieb Michael S:
>
>> That is why I don't use multiplication. Did you ever asked yourself
>> what is the meaning of 'f' in 'fma' ?
>
> The FMA-instructions produce the same results:
>
> #include <iostream>
> #include <random>
> #include <bit>
> #include <cmath>
> #include <iomanip>
> #include <intrin.h>
>
> using namespace std;
>
> int main()
> {
> auto fma = []( double a, double b, double c )
> {
> __m128d mA, mB, mC;
> mA.m128d_f64[0] = a;
> mB.m128d_f64[0] = b;
> mC.m128d_f64[0] = c;
> return _mm_fmadd_pd( mA, mB, mC ).m128d_f64[0];
> };
> mt19937_64 mt;
> uniform_int_distribution<uint64_t> finites( 1, 0x7FEFFFFFFFFFFFFFu );
> auto rnd = [&]() -> double { return
> bit_cast<double>( finites( mt ) ); };
> ptrdiff_t nEQs = 0;
> for( ptrdiff_t r = 0; r != 1'000'000; ++r )
> {
> double
> a = rnd(), b = rnd(), c = rnd(),
> rA = fma( a, b, c ),
> rB = a * b + c;
> nEQs = rA != rB;
> }
> cout << hexfloat << nEQs / 1.0e6 << endl;
> }
>
There's a good reason to produce the same result: if a "a * b + c"
-statement is replaced with a FMA-operation by the compiler you won't
get different results depending on the compiler-setting. clang++ does
this replacement if you chose the proper instruction set.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-25 17:26 +0200 |
| Message-ID | <20250225172618.00005646@yahoo.com> |
| In reply to | #121708 |
On Tue, 25 Feb 2025 09:09:21 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
> Am 24.02.2025 um 16:52 schrieb Michael S:
>
> > That is why I don't use multiplication. Did you ever asked yourself
> > what is the meaning of 'f' in 'fma' ?
>
> The FMA-instructions produce the same results:
>
> #include <iostream>
> #include <random>
> #include <bit>
> #include <cmath>
> #include <iomanip>
> #include <intrin.h>
>
> using namespace std;
>
> int main()
> {
> auto fma = []( double a, double b, double c )
> {
> __m128d mA, mB, mC;
> mA.m128d_f64[0] = a;
> mB.m128d_f64[0] = b;
> mC.m128d_f64[0] = c;
> return _mm_fmadd_pd( mA, mB, mC ).m128d_f64[0];
> };
> mt19937_64 mt;
> uniform_int_distribution<uint64_t> finites( 1,
> 0x7FEFFFFFFFFFFFFFu ); auto rnd = [&]() -> double { return
> bit_cast<double>( finites( mt ) ); }; ptrdiff_t nEQs = 0;
> for( ptrdiff_t r = 0; r != 1'000'000; ++r )
> {
> double
> a = rnd(), b = rnd(), c = rnd(),
> rA = fma( a, b, c ),
> rB = a * b + c;
> nEQs = rA != rB;
> }
> cout << hexfloat << nEQs / 1.0e6 << endl;
> }
>
GIGO.
Do a proper test then you'd get a proper answer.
fma.c:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argz, char** argv)
{
if (argz < 4) {
fprintf(stderr, "Usage:\nfma x y z\n");
return 1;
}
double values[3];
for (int i = 0; i < 3; ++i) {
char* arg = argv[i+1];
char* endp;
values[i] = strtod(arg, &endp);
if (arg == endp) {
fprintf(stderr, "Bad argument '%s'. Not a number.\n", arg);
return 1;
}
}
double r1 = values[0]* values[1] + values[2];
double r2 = fma(values[0], values[1], values[2]);
printf(" %.17e * %.17e + %.17e = %.17e\n",
values[0], values[1], values[2], r1);
printf("fma(%.17e , %.17e , %.17e) = %.17e\n",
values[0], values[1], values[2], r2);
return 0;
}
$ gcc -O2 -Wall fma.c -o fma
$ ./fma 1000000001 999999999 -1e18
1.00000000100000000e+09 * 9.99999999000000000e+08 +
-1.00000000000000000e+18 = 0.00000000000000000e+00
fma(1.00000000100000000e+09 , 9.99999999000000000e+08 ,
-1.00000000000000000e+18) = -1.00000000000000000e+00
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-25 16:45 +0100 |
| Message-ID | <vpkoik$22379$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121711 |
Am 25.02.2025 um 16:26 schrieb Michael S:
> On Tue, 25 Feb 2025 09:09:21 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>
>> Am 24.02.2025 um 16:52 schrieb Michael S:
>>
>>> That is why I don't use multiplication. Did you ever asked yourself
>>> what is the meaning of 'f' in 'fma' ?
>>
>> The FMA-instructions produce the same results:
>>
>> #include <iostream>
>> #include <random>
>> #include <bit>
>> #include <cmath>
>> #include <iomanip>
>> #include <intrin.h>
>>
>> using namespace std;
>>
>> int main()
>> {
>> auto fma = []( double a, double b, double c )
>> {
>> __m128d mA, mB, mC;
>> mA.m128d_f64[0] = a;
>> mB.m128d_f64[0] = b;
>> mC.m128d_f64[0] = c;
>> return _mm_fmadd_pd( mA, mB, mC ).m128d_f64[0];
>> };
>> mt19937_64 mt;
>> uniform_int_distribution<uint64_t> finites( 1,
>> 0x7FEFFFFFFFFFFFFFu ); auto rnd = [&]() -> double { return
>> bit_cast<double>( finites( mt ) ); }; ptrdiff_t nEQs = 0;
>> for( ptrdiff_t r = 0; r != 1'000'000; ++r )
>> {
>> double
>> a = rnd(), b = rnd(), c = rnd(),
>> rA = fma( a, b, c ),
>> rB = a * b + c;
>> nEQs = rA != rB;
>> }
>> cout << hexfloat << nEQs / 1.0e6 << endl;
>> }
>>
>
> GIGO.
> Do a proper test then you'd get a proper answer.
The test is proper with MSVC since MSVC doesn't replace the
"a * b + c"-operation with a FMA-operation. With your code
it isn't guaranteed that the CPU-specific FMA-operations are
used. I'm using the SSE FMA operation explicitly and I'm using
it for a million random finite double-values.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-25 16:57 +0100 |
| Message-ID | <vpkp99$227e0$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121712 |
This is a somewhat more improved code that generates a larger
part of zeores, denormals, infs and nans. It tests a billion
of random values for a, b and c. It is specified behaivour
according to the Intel manuals that the result is the same.
#include <iostream>
#include <random>
#include <bit>
#include <cmath>
#include <iomanip>
#include <cassert>
#include <intrin.h>
using namespace std;
int main()
{
auto fma = []( double a, double b, double c )
{
__m128d mA, mB, mC;
mA.m128d_f64[0] = a;
mB.m128d_f64[0] = b;
mC.m128d_f64[0] = c;
return _mm_fmadd_pd( mA, mB, mC ).m128d_f64[0];
};
mt19937_64 mt;
uniform_int_distribution<uint64_t>
genFinite( 0x0010000000000000u, 0x7FEFFFFFFFFFFFFFu ),
genDen( 1, 0x000FFFFFFFFFFFFFu ),
genNaN( 0x7FF0000000000001u, 0x7FFFFFFFFFFFFFFFu );
auto get = [&]()
{
constexpr uint64_t
FINITE_THRESH = 4, // 75% finites
ZERO = 3, // 6.25% zeroes
DENORMALS = 2, // 6.25% denormals
INF = 1, // 6.25% infs
NAN_THRESH = 0; // 6.25% NaNs
uint64_t
sign = mt() & numeric_limits<int64_t>::min(),
type = mt() % 16;
if( type >= FINITE_THRESH )
return bit_cast<double>( sign | genFinite( mt ) );
if( type == ZERO )
return bit_cast<double>( sign );
if( type == DENORMALS )
return bit_cast<double>( sign | genDen( mt ) );
if( type == INF )
return bit_cast<double>( sign | 0x7FF0000000000000u );
assert(type == NAN_THRESH);
return bit_cast<double>( sign | genNaN( mt ) );
};
ptrdiff_t nEQs = 0;
for( ptrdiff_t r = 0; r != 1'000'000'000; ++r )
{
double
a = get(), b = get(), c = get(),
rA = fma( a, b, c ),
rB = a * b + c;
nEQs = rA != rB;
}
cout << nEQs << endl;
}
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-25 19:17 +0200 |
| Message-ID | <20250225191715.00001a55@yahoo.com> |
| In reply to | #121712 |
On Tue, 25 Feb 2025 16:45:25 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
> Am 25.02.2025 um 16:26 schrieb Michael S:
> > On Tue, 25 Feb 2025 09:09:21 +0100
> > Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >
> >> Am 24.02.2025 um 16:52 schrieb Michael S:
> >>
> >>> That is why I don't use multiplication. Did you ever asked
> >>> yourself what is the meaning of 'f' in 'fma' ?
> >>
> >> The FMA-instructions produce the same results:
> >>
> >> #include <iostream>
> >> #include <random>
> >> #include <bit>
> >> #include <cmath>
> >> #include <iomanip>
> >> #include <intrin.h>
> >>
> >> using namespace std;
> >>
> >> int main()
> >> {
> >> auto fma = []( double a, double b, double c )
> >> {
> >> __m128d mA, mB, mC;
> >> mA.m128d_f64[0] = a;
> >> mB.m128d_f64[0] = b;
> >> mC.m128d_f64[0] = c;
> >> return _mm_fmadd_pd( mA, mB, mC ).m128d_f64[0];
> >> };
> >> mt19937_64 mt;
> >> uniform_int_distribution<uint64_t> finites( 1,
> >> 0x7FEFFFFFFFFFFFFFu ); auto rnd = [&]() -> double { return
> >> bit_cast<double>( finites( mt ) ); }; ptrdiff_t nEQs = 0;
> >> for( ptrdiff_t r = 0; r != 1'000'000; ++r )
> >> {
> >> double
> >> a = rnd(), b = rnd(), c = rnd(),
> >> rA = fma( a, b, c ),
> >> rB = a * b + c;
> >> nEQs = rA != rB;
> >> }
> >> cout << hexfloat << nEQs / 1.0e6 << endl;
> >> }
> >>
> >
> > GIGO.
> > Do a proper test then you'd get a proper answer.
>
> The test is proper with MSVC since MSVC doesn't replace the
> "a * b + c"-operation with a FMA-operation.
Don't invent your own fma(). Use one provided by library.
Then MSVC will do what it is prescribed to do by the standard.
> With your code
> it isn't guaranteed that the CPU-specific FMA-operations are
> used.
Correct. And it does not matter. When run on CPU without HW FMA, it
would be slower. But would still produce a right result.
> I'm using the SSE FMA operation explicitly and I'm using
> it for a million random finite double-values.
>
Originally, I didn't even try to investigate what garbage exactly you
are feeding to your test. Now I took a look. It seems that you are
doing something fundamentally stupid, like all fma inputs positive.
Of course, for all positive inputs the (fma(x,y,z) != x*y+z) is quite
rare. It still happens sometimes, but it's likely that for your chosen
distribution it happens less often than once per million.
OTOH, when x*y and z have different signs and similar magnitude, it
happens all the time. Still, for your stupidly chosen distribution the
similar magnitude is probably quite rare too.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-25 18:58 +0100 |
| Message-ID | <vpl0bu$247fb$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121714 |
Am 25.02.2025 um 18:17 schrieb Michael S: > Don't invent your own fma(). Use one provided by library. > Then MSVC will do what it is prescribed to do by the standard. I want to be sure that I'm using the SSE FMA operation and not a conventional substitute of two instructions. > Originally, I didn't even try to investigate what garbage exactly you > are feeding to your test. Now I took a look. It seems that you are > doing something fundamentally stupid, like all fma inputs positive. I extended the test to incorporate all possible double bitrepresentations (taken von mt()) - with no difference.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-26 00:36 +0200 |
| Message-ID | <20250226003549.0000251b@yahoo.com> |
| In reply to | #121715 |
On Tue, 25 Feb 2025 18:58:23 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
> Am 25.02.2025 um 18:17 schrieb Michael S:
>
> > Don't invent your own fma(). Use one provided by library.
> > Then MSVC will do what it is prescribed to do by the standard.
>
> I want to be sure that I'm using the SSE FMA operation
SSEn has no FMA operations.
FMA was introduces as part of AVX series, simulatneously with AVX2.
In practice all CPUs that support AVX2 also support FMA, but
from formal perspective they AVX2 and FMA are different extensions.
> and
> not a conventional substitute of two instructions.
>
fma() is guaranteed to do a right thing by standard.
It can not be substituted by two instructions. It's either one
instruction or many, likely over dozen. Never two.
> > Originally, I didn't even try to investigate what garbage exactly
> > you are feeding to your test. Now I took a look. It seems that you
> > are doing something fundamentally stupid, like all fma inputs
> > positive.
>
> I extended the test to incorporate all possible double
> bitrepresentations (taken von mt()) - with no difference.
>
What you wrote makes no sense. For positive double-precision x, y and
z there are 2**189 posible combinations. You cant check all of them even
if you were given all computers of the world for millenium.
However now I see that there indeed is a bug in Microsoft's
implementation of fma() library routine (also used by gcc on msys2).
When programs linked with their dynamic library run on hardware with FMA
instructions then everything works correctly.
Same programs on hardware without FMA mostly produce correct results
when x*y and z differ in sign.
But when x*y and z have the same sign then [on hardware without FMA]
Microsoft's routine appear to do non-fused calculations.
Here is an example of the program that prints 250508 on Intel Haswell
CPU, but prints 0 on Intel Ivy Bridge.
Compiled as 'cl -O1 -W4 -MD fma_tst0.c'.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static
unsigned long long rnd(void)
{
unsigned long long x = 0;
for (int i = 0; i < 5; ++i)
x = (x << 15) + (rand() & 0x7FFF);
return x;
}
int main(void)
{
srand(1);
int n = 0;
for (int i = 0; i < 1000000; ++i) {
double x = rnd() * 0x1p-64;
double y = rnd() * 0x1p-64;
double z = rnd() * 0x1p-114;
double r1 = x*y + z;
double r2 = fma(x, y, z);
n += r1 != r2;
}
printf("%d\n", n);
return 0;
}
It is certainly worth a bug report, but I am afraid that Microsoft will
do nothing to fix it, likely claiming that they don't care about old
hardware.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-02-26 04:15 +0100 |
| Message-ID | <vpm10k$29kjv$1@raubtier-asyl.eternal-september.org> |
| In reply to | #121716 |
Am 25.02.2025 um 23:36 schrieb Michael S: > SSEn has no FMA operations. FMA3 is an extension to SSE as well as AVX. As you can see from my code I'm using the __m128d data type, which is a SSE and not an AVX data type. There are also variants for AVX (ymm) and AVX-512 (zmm) data types.
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-02-26 08:16 +0000 |
| Message-ID | <vpmik1$2frhi$1@dont-email.me> |
| In reply to | #121716 |
On Wed, 26 Feb 2025 00:36:19 +0200
Michael S <already5chosen@yahoo.com> wibbled:
>Here is an example of the program that prints 250508 on Intel Haswell
>CPU, but prints 0 on Intel Ivy Bridge.
>Compiled as 'cl -O1 -W4 -MD fma_tst0.c'.
>
>#include <stdio.h>
>#include <stdlib.h>
>#include <math.h>
>
>static
>unsigned long long rnd(void)
>{
> unsigned long long x = 0;
> for (int i = 0; i < 5; ++i)
> x = (x << 15) + (rand() & 0x7FFF);
> return x;
>}
>
>int main(void)
>{
> srand(1);
> int n = 0;
> for (int i = 0; i < 1000000; ++i) {
> double x = rnd() * 0x1p-64;
> double y = rnd() * 0x1p-64;
> double z = rnd() * 0x1p-114;
> double r1 = x*y + z;
> double r2 = fma(x, y, z);
> n += r1 != r2;
> }
> printf("%d\n", n);
> return 0;
>}
>
>It is certainly worth a bug report, but I am afraid that Microsoft will
>do nothing to fix it, likely claiming that they don't care about old
>hardware.
Just FYI - it also returns 0 when compiled by Clang on an ARM Mac.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-26 14:27 +0200 |
| Message-ID | <20250226142721.0000375b@yahoo.com> |
| In reply to | #121721 |
On Wed, 26 Feb 2025 08:16:01 -0000 (UTC)
Muttley@DastardlyHQ.org wrote:
> On Wed, 26 Feb 2025 00:36:19 +0200
> Michael S <already5chosen@yahoo.com> wibbled:
> >Here is an example of the program that prints 250508 on Intel Haswell
> >CPU, but prints 0 on Intel Ivy Bridge.
> >Compiled as 'cl -O1 -W4 -MD fma_tst0.c'.
> >
> >#include <stdio.h>
> >#include <stdlib.h>
> >#include <math.h>
> >
> >static
> >unsigned long long rnd(void)
> >{
> > unsigned long long x = 0;
> > for (int i = 0; i < 5; ++i)
> > x = (x << 15) + (rand() & 0x7FFF);
> > return x;
> >}
> >
> >int main(void)
> >{
> > srand(1);
> > int n = 0;
> > for (int i = 0; i < 1000000; ++i) {
> > double x = rnd() * 0x1p-64;
> > double y = rnd() * 0x1p-64;
> > double z = rnd() * 0x1p-114;
> > double r1 = x*y + z;
> > double r2 = fma(x, y, z);
> > n += r1 != r2;
> > }
> > printf("%d\n", n);
> > return 0;
> >}
> >
> >It is certainly worth a bug report, but I am afraid that Microsoft
> >will do nothing to fix it, likely claiming that they don't care
> >about old hardware.
>
> Just FYI - it also returns 0 when compiled by Clang on an ARM Mac.
>
Looks like a bug in clang.
New versions of clang generate FMA instead of mul+add. I.e. clang bug is
opposite of MS bug.
By Standard, compilers not allowed to do it in "standard" C mode in
absence of special flags like -ffast-math.
I played a little on godbolt and it seems that the bug is relatively
new. clang 13 still generates correct code. clang 14 does not. I.e.
slightly less than 3 years.
It happened simultaneously on x86-64 and ARM64
clang 14
https://godbolt.org/z/asochKz5P
https://godbolt.org/z/c7xTaGWzv
clang 13
https://godbolt.org/z/6onP3dE3c
https://godbolt.org/z/W9exqTanf
clang 13 -ffast-math
https://godbolt.org/z/8f875qMrf
https://godbolt.org/z/qPGafr563
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-02-26 14:39 +0000 |
| Message-ID | <vpn935$2jodr$1@dont-email.me> |
| In reply to | #121722 |
On Wed, 26 Feb 2025 14:27:21 +0200 Michael S <already5chosen@yahoo.com> wibbled: >On Wed, 26 Feb 2025 08:16:01 -0000 (UTC) >Muttley@DastardlyHQ.org wrote: >I played a little on godbolt and it seems that the bug is relatively >new. clang 13 still generates correct code. clang 14 does not. I.e. >slightly less than 3 years. I don't think they've noticed: R8603$ cc --version Apple clang version 16.0.0 (clang-1600.0.26.6)
[toc] | [prev] | [next] | [standalone]
Page 1 of 7 [1] 2 3 4 5 6 7 Next page →
Back to top | Article view | comp.lang.c++
csiph-web