Search code examples
assemblyx86floating-pointsse

What does ordered / unordered comparison mean?


Looking at the SSE operators

CMPORDPS - ordered compare packed singles
CMPUNORDPS - unordered compare packed singles

What do ordered and unordered mean? I looked for equivalent instructions in the x86 instruction set, and it only seems to have unordered (FUCOM).


Solution

  • An ordered comparison checks if neither operand is NaN. Conversely, an unordered comparison checks if either operand is a NaN.

    This page gives some more information on this:

    The idea here is that comparisons with NaN are indeterminate. (can't decide the result) So an ordered/unordered comparison checks if this is (or isn't) the case.

    double a = 0.;
    double b = 0.;
    
    __m128d x = _mm_set1_pd(a / b);     //  NaN
    __m128d y = _mm_set1_pd(1.0);       //  1.0
    __m128d z = _mm_set1_pd(1.0);       //  1.0
    
    __m128d c0 = _mm_cmpord_pd(x,y);    //  NaN vs. 1.0
    __m128d c1 = _mm_cmpunord_pd(x,y);  //  NaN vs. 1.0
    __m128d c2 = _mm_cmpord_pd(y,z);    //  1.0 vs. 1.0
    __m128d c3 = _mm_cmpunord_pd(y,z);  //  1.0 vs. 1.0
    __m128d c4 = _mm_cmpord_pd(x,x);    //  NaN vs. NaN
    __m128d c5 = _mm_cmpunord_pd(x,x);  //  NaN vs. NaN
    
    cout << _mm_castpd_si128(c0).m128i_i64[0] << endl;
    cout << _mm_castpd_si128(c1).m128i_i64[0] << endl;
    cout << _mm_castpd_si128(c2).m128i_i64[0] << endl;
    cout << _mm_castpd_si128(c3).m128i_i64[0] << endl;
    cout << _mm_castpd_si128(c4).m128i_i64[0] << endl;
    cout << _mm_castpd_si128(c5).m128i_i64[0] << endl;
    

    Result:

    0
    -1
    -1
    0
    0
    -1
    

    Ordered return true if the operands are comparable (neither number is NaN):

    • Ordered comparison of 1.0 and 1.0 gives true.
    • Ordered comparison of NaN and 1.0 gives false.
    • Ordered comparison of NaN and NaN gives false.

    Unordered comparison is the exact opposite:

    • Unordered comparison of 1.0 and 1.0 gives false.
    • Unordered comparison of NaN and 1.0 gives true.
    • Unordered comparison of NaN and NaN gives true.