octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #54572] int64 does not saturate correctly in n


From: Dan Sebald
Subject: [Octave-bug-tracker] [bug #54572] int64 does not saturate correctly in negative direction
Date: Wed, 29 Aug 2018 19:15:04 -0400 (EDT)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0

Follow-up Comment #33, bug #54572 (project octave):

I'm not even sure the OCTAVE_HAVE_FAST_INT_OPS is that much more efficient
than the alternate.  If I had the energy, I'd compile both versions and look
at the assembly, but just counting operations...

IN THE NO OVERFLOW CASE


#if defined (OCTAVE_HAVE_FAST_INT_OPS)
    // The typecasts do nothing, but they are here to prevent an optimizing
    // compiler from interfering.  Also, the signed operations on small types
    // actually return int.
    T u = static_cast<UT> (x) - static_cast<UT> (y); [1 op]
    T ux = u ^ x;                                    [1 op]
    T uy = u ^ ~y;                                   [2 op]
    if ((ux & uy) < 0)                               [1 op ... comparing
against 0 is is a JMPZ or something]
      {
        u = (__signbit (~u)
             ? octave_int_base<T>::min_val ()
             : octave_int_base<T>::max_val ());
      }
    return u;


5 operations and a few save/loads/jmps unless optimization is good.


    // We shall carefully avoid anything that may overflow.
    T u;
    if (y < 0)                                        [1 op]
      {
        if (x > octave_int_base<T>::max_val () + y)   [2 op]
          {
            u = octave_int_base<T>::max_val ();
          }
        else
          u = x - y;                                  [1 op]
      }
    else
      {
        if (x < octave_int_base<T>::min_val () + y)
          {
            u = octave_int_base<T>::min_val ();
          }
        else
          u = x - y;
      }

    return u;


4 operations and a few load/save/jmp.

On operations alone, it looks like the "slower" routine has less of them. 
Granted, in the second case we are always loading that min_val and there is
probably one or two more jumps, but this is so close that I'd think it depends
on the compiler and architecture pipelining as to which is faster.


IN THE OVERFLOW CASE


#if defined (OCTAVE_HAVE_FAST_INT_OPS)
    // The typecasts do nothing, but they are here to prevent an optimizing
    // compiler from interfering.  Also, the signed operations on small types
    // actually return int.
    T u = static_cast<UT> (x) - static_cast<UT> (y); [1 op]
    T ux = u ^ x;                                    [1 op]
    T uy = u ^ ~y;                                   [2 op]
    if ((ux & uy) < 0)                               [1 op]
      {
        u = (__signbit (~u)                          [2 op]
             ? octave_int_base<T>::min_val ()
             : octave_int_base<T>::max_val ());
      }
    return u;


7 operations and a few save/loads/jmps unless optimization is good.


    // We shall carefully avoid anything that may overflow.
    T u;
    if (y < 0)                                        [1 op]
      {
        if (x > octave_int_base<T>::max_val () + y)   [2 op]
          {
            u = octave_int_base<T>::max_val ();
          }
        else
          u = x - y;
      }
    else
      {
        if (x < octave_int_base<T>::min_val () + y)
          {
            u = octave_int_base<T>::min_val ();
          }
        else
          u = x - y;
      }

    return u;


3 operations and a few load/save/jmp.

The supposed slower method is a clear winner in this case.  The former
OCTAVE_HAVE_FAST_INT_OPS is more than anything conserving code space because
of reduced jumps.

I'd advocate replacing that OCTAVE_HAVE_FAST_INT_OPS group with the
GCC-compiler __building_ssubll_overflow() class of routines to get a certain
speed-up.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?54572>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]