News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Integer versus Single

Started by frktons, November 07, 2021, 09:52:13 AM

Previous topic - Next topic

frktons

Hello my ASM addicted friends.  :thumbsup:
I have a question as a newbie that has surely a simple answer.
If I have to compare 1 million Integer number between themselves, and a million
Single precision numbers between themselves, which operation will cost more time?

Thanks for any help

Frank
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

Biterider

Hi
Well formed REAL4 numbers can be compared using the CPU as if they were DWORDs.
Particular caution is required with infinities and NANs. If you can rule out these cases, the comparison should take the same amount of time.

Biterider

mineiro

I don't know the answer, should be a testcase.
As noted, you can compare real4 as being dword integers, a xor instruction for equality gives you an answer.
New cpu's can use packed (paralell) comparisions, in one xmm (128 bits) register you can perform 4 real4 comparisions with 1 load to register operation, but if you have a 64 bits and using xor as a test for equality you can perform 2 comparisions at time spending 2 loads to register operations.
But, if you're trying to find for real4/8 bigger than, less than, I think packed instructions can do better; or you can try to mix logic/arithmetic operations with integers to do the same job (bit scan).
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

jj2007

There is a long thread in the old forum (it led to the Fcmp macro). Basically, the problem is that "equal" is a tough concept for floating point values. They rarely are equal. For example, PI is not 3.141592653589793238

hutch--

I imagine that a float "1234.5678" can be compared to another float to see if its the same or different. Its when the numbers have many integers after the decimal point that the chances of an exact match become much harder. You could probably make a rounding theory set to a range that equated to a match or not, depends on the required precision level.

frktons

Thanks everybody for your answers.

My problem to solve is a bit more simple, and a bit more long, because I don't need to have
a perfect match for equal. I only need to test if a value is bigger or smaller than another one.

I also need to perform a subtraction in order to know also the
quantity of the difference between the two numbers.

Let's say, for a first example, that I need to know if the difference is >= +/-10.

The real situation is that I just have ASCII to represent the single digit, not real REAL NUMBERS.

So I have the ASCII "1234.1234" and I have to compare it with the ASCII "1246.2431".

The numbers are in the range NNNN.NNNN to NNNN.NNNN (four digits for integer part and the same for decimals. 8 digits in all.

It is a double step operation to do, I think.

First I have to to transform 2 STRINGS into 2 NUMBERS and then to compare them.

In my mind I think a feasible solution is to skip the decimal point, convert the STRING into a LONG INTEGER or a REAL NUMBER
and then subtract the two INTEGER/REAL numbers. Instead of testing for a difference of 10, I can test for 1,000 or 10,000 or 100,000
depending on the numbers of digit after the decimal point.

Moreover, because I don't need an extreme precision, but just a raw > 10 or < -10 difference between the two numbers, I could
probably skip the decimals without compromising my solution.


Any thought around this goal?

I have to find a fast way to convert a million strings into a million numbers.
Then I have to compare them for a difference of > +10 or < -10

Enjoy your day
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

daydreamer

I have been trying doing SIMD solution  as exercise on ascii to float
Otherwise you get (digit-48)* with multipliers 1000,100,10,1,0.1,0.01,0.001,0.0001
And add together scalar
(8 subs,8 Fmul,7 adds) x 1 million, wonder if an ascii math library would be faster?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

mineiro

You really need to convert or just get an answer!?
I was thinking something like this, but need a bit more work and need check if really works:


align 4
output  db "1000","1000","1000","1000","1000","1000","1000","1000"
        db "0100","0100","0100","0100","0100","0100","0100","0100"
        db "0010","0010","0010","0010","0010","0010","0010","0010"
        db "0001","0001","0001","0001","0001","0001","0001","0001"

mov esi,"<"
mov edi,">"
mov eax,"1234"              ;31323334h
mov ebx,"1246"              ;31323436h
mov ecx,eax
xor ecx,ebx                 ;00000702h
jz after_dot                ;integer part equal
and eax,ecx                 ;00000300h
and ebx,ecx                 ;00000402h

mov ecx,eax                 ;assume eax>ebx
mov edx,edi                 ;>
cmp eax,ebx                                              ;.if eax > ebx, print ">", mov ecx,eax
cmovb ecx,ebx               ;avoid jumps                 ;else print "<", mov ecx,ebx
cmovb edx,esi               ;<
;print edx

bsr ecx,ecx                 ;count digits
;----------------------------
    lea edx,output
    mov eax,dword ptr [edx+ecx*4]
    ;print eax
    jmp next_number
;----------------------------
.if ecx > 23       
    ;print "1000"
.elseif ecx > 15   
    ;print "100"
.elseif ecx > 7     
    ;print "10"
.else               
    ;print "1"
.endif
;----------------------------
jmp next_number
after_dot:



Oh, sorry, I now read your other post, ignore this message.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

raymond

#8
I currently don't know what you intend to do following your comparisons. You can have a peek at the attached code and adapt it to your needs if it may help you. It could be simplified a lot depending on the ultimate purpose.

;assuming:
;a) the numbers to be compared are in List1 and List2
;b) the numbers to be compared are always positive and are always 8 bytes long in the form of ascii text
;   with an 'assumed' decimal point after the 4th integer digit
;c) if the integer part is less than 1000, it is padded with ascii spaces, i.e. 20h

      xor   ecx,ecx
      lea   esi,List1
      lea   edi,List2
      mov   eax,List1[ecx]
      mov   ebx,List2[ecx]
      bswap eax         
      bswap ebx
      and   eax,0f0f0f0fh     ;get rid of ascii code
      and   ebx,0f0f0f0fh     ;id
      cmp   eax,ebx
      jz    equal       ;their integer parts are equal

      .if   !CARRY?     ;List1 number is greater
            push  eax   ;AH could be affected
            sub   al,bl ;subtract lower digits
            aas         ;subtract adjust
            mov   dl,al ;store result
            pop   eax   ;retrieves unchanged AH
            mov   al,ah
            sbb   al,bh ;subtract with carry 2nd lower digit
            aas
            mov   dh,al ;store result
            bswap edx
           
            bswap eax
            bswap ebx   ;get to 3rd and 4th digits
            push  eax
            xchg  al,ah
            sbb   al,bh
            aas
            mov   dh,al
            pop   eax
            sbb   al,bl
            aas
            mov   dl,al
            bswap edx
            cmp   edx,100h ;compare result of subtraction to 10
            jbe   nodiff
            jmp   list1_greater
      .else             ;subtract the List1 number from the List2 one
            xchg  eax,ebx
            push  eax   ;AH could be affected
            sub   al,bl ;subtract lower digits
            aas         ;subtract adjust
            mov   dl,al ;store result
            pop   eax   ;retrieves unchanged AH
            mov   al,ah
            sbb   al,bh ;subtract with carry 2nd lower digit
            aas
            mov   dh,al ;store result
            bswap edx
           
            bswap eax
            bswap ebx   ;get to 3rd and 4th digits
            push  eax
            xchg  al,ah
            sbb   al,bh
            aas
            mov   dh,al
            pop   eax
            sbb   al,bl
            aas
            mov   dl,al
            bswap edx
            cmp   edx,100h ;compare result of subtraction to 10
            jbe   nodiff
            jmp   list2_greater
      .endif

nextone:
      add   ecx,8
      cmp   ecx,maxfilesize
      jb    start1
      jmp   finish

equal:      ;the integer parts of both numbers are equal
      ;do whatever is needed
      jmp   nextone

nodiff:     ;the integer parts of both numbers are within 10
      ;do whatever is needed
      jmp   nextone

list1_greater:
      ;do whatever is needed
      jmp   nextone

list2_greater:
      ;do whatever is needed
      jmp   nextone


Getting the difference of two ascii numbers was a little trickier than I had originally assumed.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

daydreamer

#9
Great raymond  :thumbsup:



my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

raymond

Please see my modified post (which will be made within a short time from now)
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

daydreamer

just some SIMD code,from my avxcalculator exercise

.data
mulint dq 0001000A006403E8h ;1000,100,10,1 in words
.code
movd xmm3, mulint
xorps xmm2,xmm2
mov eax, 030303030h
movd xmm2, eax
psubb xmm6, xmm2 ;subtract all bytes with 48
xorps xmm0, xmm0 ;xmm0=highbytes in unpack
PUNPCKLBW xmm6,xmm0 ; xmm0, xmm6 ;unpack bytes->words

pmullw xmm6, xmm3 ;1000*,100*,10*,1*
xorps xmm0,xmm0
PUNPCKLWD xmm6, xmm0
cvtdq2ps xmm6,xmm6
haddps xmm6,xmm6 ;horizontal add digit 1+2,digit 3+4
haddps xmm6,xmm6 ;horizontal add (1+2)+(3+4)
movss tmp2,xmm6
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding