Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #121694 > unrolled thread

a MSVC and glibc-compatible fmod()

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2025-02-24 11:48 +0100
Last post2025-03-09 14:56 +0200
Articles 20 on this page of 134 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  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 →


#121694 — a MSVC and glibc-compatible fmod()

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-02-24 11:48 +0100
Subjecta 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]


#121695

FromMuttley@DastardlyHQ.org
Date2025-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]


#121696

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121697

FromMuttley@DastardlyHQ.org
Date2025-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]


#121698

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121701

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#121702

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121704

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#121708

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121710

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121711

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#121712

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121713

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121714

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#121715

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121716

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#121720

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-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]


#121721

FromMuttley@DastardlyHQ.org
Date2025-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]


#121722

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#121723

FromMuttley@DastardlyHQ.org
Date2025-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