Thread: Faster bitwise operator

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    147
    Back to "Is != or < faster?" specifically, let me invoke a hint of history here.

    This is the same in C or C++; they are elementary statements.

    C was originally written to replace an assembler, essentially to be a chip independent assembler or just slightly higher than assembler.

    Many constructs in the elementary syntax of C (and therefore C++) translate into 1 assembler instruction, when a chip supports that as such. These two happen to translate to x86 instructions of identical meaning (!= or <, >, >=, <=, etc).

    As such, the speed of such comparisons, or of any of the elementary constructs like this, will relate closely to the chip on which you're executing. So, from a language viewpoint, it hardly makes sense to think of this in terms of the "language speed", but of the fact that implementations differ, optimizations may significantly affect some of the basic constructs and you generally shouldn't focus on microscopic performance issues too early. There are very rare exceptions to this general rule, and by the time you get to the point that it matters in your work, you'll have some sense of the assembler implications of your C/C++ code anyway, and the question will be moot.

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Does anyone know which (x86) instructions those operators boil down to?
    All you'd need to do is see how many clock cycles each of those instructions takes and compare their speed, right?

    Although, without knowing too much about chip implementations, the only guess I can make as to why one might be faster is that != would just compare the binary representation of the two numbers, whereas < or > would need to check the sign of the variable for a signed int and then compare the numbers (whether the CPU can check the sign and do the compare at the same time, I have no idea).
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by cpjust View Post
    Does anyone know which (x86) instructions those operators boil down to?
    All you'd need to do is see how many clock cycles each of those instructions takes and compare their speed, right?
    For Integers, It should boil down to CMP R2,R1 (or however registers are names) followed by either JE or JGE. JE and JGE both just check the control flags, and are therefore trivial operations. For floating point it would use FCOM, instead of CMP.

    So for primitives there is no difference.
    Last edited by King Mir; 04-27-2009 at 09:11 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Registered User
    Join Date
    May 2007
    Posts
    147
    cpjust

    x86 does as King Mir states - cmp is the generic call to perform a comparison - it is very much like a subtraction. In x86, subtractions and cmp set flags in the CPU, indicating things like sign, zero flag, overflow - various technical results. After that, a conditional jump instruction is what makes the decision as to truth or falsehood of a particular comparison like <, !=, etc. All of these have the same cycle count - so the answer you've received is the best you can get - they are basically the same. There is no point in asking which is faster.

    What makes this a little more complicated is the various CPU's ability to predict branches, cache reaction to branches, hyperthreading, speed of RAM, alignment in RAM, whether or not the cmp is applied to a register or memory location (I forget if/when that was or was not possible in x86)....

    In other words, you're focused on such a microscopic level of performance that you probably can't get the results you're hoping for without deciding to code in assembler - and even that isn't likely to be all that productive in this case.

    Each model CPU and combination of hardware could make some difference.
    Last edited by JVene; 04-27-2009 at 09:56 PM.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    For the processor (all the common ones at least) they are surely absolutely equal.
    For a bignum class the < would be slightly slower because it involves two comparisons in the loop (excluding the loop condition) rather than just one:
    Code:
    {
        if (a.data[i] < b.data[i]) return true;
        if (a.data[i] > b.data[i]) return false;
        // else continue iterating.
    }
    
    // vs
    
    {
        if (a.data[i] != b.data[i]) return false;
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    iMalc:iMalc - good point, but we could do that in a different way:
    Code:
       int cmp;
       for(...)
       {
          if ((cmp = a.data[i] - b.data[i]));
          {
             return (cmp > 0)?true:false; 
          }
       }
    This assumes that the common case is similar numbers. But I don't think it's much worse for the case with immediately different numbers - and that is the fast case in either variant, anyways.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by matsp View Post
    iMalc:iMalc - good point, but we could do that in a different way:
    Code:
       int cmp;
       for(...)
       {
          if ((cmp = a.data[i] - b.data[i]));
          {
             return (cmp > 0)?true:false; 
          }
       }
    This assumes that the common case is similar numbers. But I don't think it's much worse for the case with immediately different numbers - and that is the fast case in either variant, anyways.

    --
    Mats
    That at first seemed like a great idea, and would work for people who have implemented something where each decimal digit is stored in an int or something wasteful like that, but it wont work for a "wasteless" implementation where the bigint is an array of unsigned longs. The reason being that the result of the subtraction would have to range from 0xFFFFFFFFU - 0 to 0 - 0xFFFFFFFFU. So that's -0xFFFFFFFF to +0xFFFFFFFF, requring an extra bit, as well as casting to a signed datatype. Of course it will work if you cast both to a larger datatype first, however I imagine the efficiency will then come out about the same as the original way I posted. Well, maybe still a little ahead if you're lucky.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. C bitwise operator exercise - more like newb killer
    By shdwsclan in forum C Programming
    Replies: 3
    Last Post: 02-22-2006, 07:02 AM
  4. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM
  5. Replies: 5
    Last Post: 10-30-2002, 10:23 PM