flat assembler
Message board for the users of flat assembler.

Index > Main > Progress Bar Counting.

Goto page Previous  1, 2
Author
Thread Post new topic Reply to topic
edfed



Joined: 20 Feb 2006
Posts: 4350
Location: Now
edfed 03 Aug 2011, 13:36
JohnFound wrote:
Madis731 wrote:
I usually avoid divisions and in this case I would make the progress bar a
multiple of 2 i.e. 64. That way your div becomes shr 6. There are even samples out there to divide by 80 (the console width) without using div instruction.

You have to divide to the size_of_the_whole, not the length of the progress bar. See the above formulas.
You can try to use subtraction instead of division (like in Bresenham's algorithm), but it will work only on incremental progress.

besenham can work in all direction with only one algo.

you just have to define the Xinc and Yinc =1.
test for sign of deltaY and deltaX, and negate the corresponding ?inc value.

then:
start at X0,Y0
load the absolute value of maximal delta as a counter
load the half of the absolute value of maximal delta as an initial condition of the substractive division.
then, you can start to compute the state of every dot along the maximal delta direction.


the besenham algo is not a good solution for the progress bar.
it is only good for interpolation beetwen two points, for example, create audio sample beetwen two samples, create a greyscale, create any line in any 2D environment (don't mean graphic only).
the progress bar is not 2D, it is 1D only, with a simple scale from a side to another of the same D that is the progress ratio vs the process size.
Post 03 Aug 2011, 13:36
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 03 Aug 2011, 14:02
Bresenham's algorithm is not limited to 2D - it can be used for arbitrary dimensioned space. In the case of progress bar - it is 1D.
Although I still think, in the case of progress bar, simple formula computation with integer division will give the smallest and most clean and readable result.
Post 03 Aug 2011, 14:02
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20656
Location: In your JS exploiting you and your system
revolution 03 Aug 2011, 14:13
Erm, perhaps a reality check is in order here. 'div' is a perfectly sensible and appropriate instruction to use for computing things like progress bars. Ask yourself how often are you updating the bar? Perhaps not more than 10 times per second (and probably a bit less). You might save, say, 20 clock cycles per 'div' with an alternative. But it would take you at least 10, or more, minutes to program and debug the 'div' alternative. That equates to a payback time of 285 years (with a 3GHz CPU) before alternative 'div' methods become sensible to code. Doing 10 'div's a second by other methods (i.e. magic constants etc.) is not going to be worth all the extra coding and debugging effort required to replace the 'div'.

I hope I got the maths right there.
Post 03 Aug 2011, 14:13
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4350
Location: Now
edfed 03 Aug 2011, 14:26
you didn't consider the diffusion of code on the web.

let say, if a code is adopted in something used by 1 000 000 people, you can divide the payback time by one million. then, two days and 12 hours approximatelly.

but as div is a good instruction, present, let use it!!!
Post 03 Aug 2011, 14:26
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20656
Location: In your JS exploiting you and your system
revolution 03 Aug 2011, 14:28
edfed wrote:
you didn't consider the diffusion of code on the web.

let say, if a code is adopted in something used by 1 000 000 people, you can divide the payback time by one million. then, two days and 12 hours approximatelly.
Show me a million people that use their CPU at 100% constantly and then I will start writing alternative 'div' codes everywhere. Razz
Post 03 Aug 2011, 14:28
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4350
Location: Now
edfed 03 Aug 2011, 14:32
everywhere there are critical real time applications, there are 100% use of CPU. it don't means it saturate it, but it can just use the maximal ressource it can just to be more real time, and maybe predict a little with the extra % it takes instead of let the cpu hlt.
Post 03 Aug 2011, 14:32
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20656
Location: In your JS exploiting you and your system
revolution 03 Aug 2011, 14:45
edfed wrote:
everywhere there are critical real time applications, there are 100% use of CPU. it don't means it saturate it, but it can just use the maximal ressource it can just to be more real time, and maybe predict a little with the extra % it takes instead of let the cpu hlt.
So what you need to do now is find one million of these overworked critical systems that also have operators watching progress bars all day. Razz Razz

Perhaps for this download progress bar it would be worth it.


Description: Download the Internet.
Filesize: 11.93 KB
Viewed: 9010 Time(s)

Downloading Internet.gif


Post 03 Aug 2011, 14:45
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4350
Location: Now
edfed 03 Aug 2011, 15:05
lol. insert A:
Post 03 Aug 2011, 15:05
View user's profile Send private message Visit poster's website Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2893
Location: 0x77760000
typedef 03 Aug 2011, 15:32
download the whole internet. lol

as George Bush would say "Internets"
Post 03 Aug 2011, 15:32
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4350
Location: Now
edfed 03 Aug 2011, 16:54
is the 23,993,564,998MB value exact?

a progress bar can also be used as a vu-meter. and there are a lot of vu-meters on a scenic console screen.
Post 03 Aug 2011, 16:54
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20656
Location: In your JS exploiting you and your system
revolution 03 Aug 2011, 17:00
edfed wrote:
is the 23,993,564,998MB value exact?
No. The exact byte count has been rounded too the nearest megabyte. So it could be wrong by as much as 2.08389e-9%
Post 03 Aug 2011, 17:00
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4350
Location: Now
edfed 03 Aug 2011, 17:02
if i run my apache server, we can add several megabytes to the count.
Post 03 Aug 2011, 17:02
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
Madis731 04 Aug 2011, 07:20
Actually I do get the algorithm and I've made progress bars before. What I meant is if your bar is 64 units in length, then your floppy image (1457664 bytes) download will happen in 64 increments. You would have to update your progressbar ONLY! when another 22776 bytes have passed not any sooner. No need to update 10 times per second.

Code is simple:
Code:
mov eax,SIZE_OF_FILE ; 1457664
shr eax,6 ; progress bar increments
jz  .done
mov ebx,eax
;...
@@:
  hlt
  cmp  ebx,[transferred]
  jnc  @b
  call updateProgressBar
  add  ebx,eax ;ebx has the new "epoch" to run to
  jmp  @b
.done:
    


...and it didn't take 20minutes.

I'm afraid of using div because I know it behaves badly when you divide by 0 and you need to check for this before division. Next probleb is that is uses edx:eax so you need to clear edx because otherwise the results don't mean anything. What if you have already used edx? You'd need to move it to another register.

So I'm not only counting clocks with div, but the problem with it is that I need to do so much more than with mul or add or other simpler ALU operations.
Post 04 Aug 2011, 07:20
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
Madis731 04 Aug 2011, 09:25
The C code was using some bad coding habits, like using float counter. The divisions on integers (if counter were integer) are made in wrong order which makes the output always 0 or 100%, but never between. I noticed that float was used, which is totally unnecessary.

Also 100000000 wraps around at about 42% because of the 32-bit counters. In 64-bit I was able to easily overcome that problem.

Code:
include 'win64a.inc'
format PE64 CONSOLE 5.0

        invoke  GetStdHandle,STD_OUTPUT_HANDLE
        mov     [hConsole],rax
        invoke  GetConsoleScreenBufferInfo,[hConsole],sbi
        mov     [iPercent],100000000;

        mov     [rCounter],1
      .for:
        mov     rax,[rCounter]
        cmp     rax,[iPercent]
        jg      .end_for

        xor     edx,edx
        mov     rbx,[iPercent]
        mov     rax,[rCounter]
        imul    rax,54
        div     rbx
        add     eax,8

        mov     [iTmpMth1],rax

        cmp     [iPrevCnt],rax
        je      @f
        movzx   ecx,word[sbi+6]
        add     ecx,3
        stdcall locate,rcx,[iTmpMth1],0,0
        ccall   [printf],"%c",219
        mov     rax,[iTmpMth1]
        mov     [iPrevCnt],rax
      @@:

        xor     edx,edx
        mov     rbx,[iPercent]
        mov     rax,[rCounter]
        imul    rax,100
        div     rbx
        mov     [iTmpMth1],rax

        cmp     [iPrevLoc],rax
        je      @f

        movzx   ecx,word[sbi+6]
        add     ecx,3
        stdcall locate,rcx,67,0,0
        ccall   [printf],"%d %",[iTmpMth1]
        mov     rax,[iTmpMth1]
        mov     [iPrevLoc],rax
      @@:
        add     [rCounter],1
        jmp     .for
      .end_for:
        movzx   ecx,word[sbi+6]
        add     ecx,5
        stdcall locate,rcx,1,1,0
        invoke  Sleep,2000
        invoke  ExitProcess,0

proc locate row,col,show,shape
        mov     [row],rcx
        mov     [col],rdx
        mov     rdx,[row]
        sub     rdx,1
        shl     rdx,16
        add     rdx,[col]
        sub     rdx,1
        invoke  SetConsoleCursorPosition,[hConsole],rdx
        mov     [cci+4],r8d ;visible
        mov     [cci],r9d ;size
        invoke  SetConsoleCursorInfo,[hConsole],cci
        ret
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          msvcrt,'msvcrt.dll'

  import kernel,\
         GetStdHandle,'GetStdHandle',\
         SetConsoleCursorPosition,'SetConsoleCursorPosition',\
         SetConsoleCursorInfo,'SetConsoleCursorInfo',\
         GetConsoleScreenBufferInfo,'GetConsoleScreenBufferInfo',\
         ExitProcess,'ExitProcess',\
         Sleep,'Sleep'

  import msvcrt,\
         printf,'printf'

  hConsole dq ?
  iPercent dq ?
  iPrevCnt dq ?
  iPrevLoc dq ?
  iTmpMth1 dq ?
  rCounter dq ?
  sbi:     rb 2+2+2+8+2 ;CONSOLE_SCREEN_BUFFER_INFO
  cci:     rb 4+4       ;CONSOLE_CURSOR_INFO
    


Its true that my idea, dividing backwards, only goes so far. Calculating percentage still needs division:
Code:
include 'win64a.inc'
format PE64 CONSOLE 5.0

        invoke  GetStdHandle,STD_OUTPUT_HANDLE
        mov     [hConsole],rax
        invoke  GetConsoleScreenBufferInfo,[hConsole],sbi
        mov     [iPercent],100000000;

        ;Precalculate bar increments:
        mov     rax,[iPercent]
        shr     eax,6 ;Now uses 64 (2^6) unit bar
        mov     [iIncrmnt],rax
        mov     [iTmpMth1],rax
        mov     [iCurLoc1],3

        mov     [rCounter],1
      .for:
        mov     rax,[rCounter]
        cmp     rax,[iPercent]
        jg      .end_for

        mov     rax,[iTmpMth1]
        cmp     [rCounter],rax
        jc      @f
        movzx   ecx,word[sbi+6]
        add     ecx,3
        stdcall locate,rcx,[iCurLoc1],0,0
        ccall   [printf],"%c",219
        mov     rax,[iIncrmnt]
        add     [iTmpMth1],rax
        add     [iCurLoc1],1
      @@:

        xor     edx,edx
        mov     rbx,[iPercent]
        mov     rax,[rCounter]
        imul    rax,100
        div     rbx
        mov     [iTmpMth2],rax

        cmp     [iPrevLoc],rax
        je      @f

        movzx   ecx,word[sbi+6]
        add     ecx,3
        stdcall locate,rcx,73,0,0
        ccall   [printf],"%d %",[iTmpMth2]
        mov     rax,[iTmpMth2]
        mov     [iPrevLoc],rax
      @@:

        add     [rCounter],1
        jmp     .for
      .end_for:
        movzx   ecx,word[sbi+6]
        add     ecx,5
        stdcall locate,rcx,1,1,0
        invoke  Sleep,2000
        invoke  ExitProcess,0

proc locate row,col,show,shape
        sub     ecx,1
        sub     edx,1
        shl     ecx,16
        add     ecx,edx
        mov     edx,ecx
        push    r8 r9
        invoke  SetConsoleCursorPosition,[hConsole],rdx
        pop     r9 r8
        mov     [cci+4],r8d ;visible
        mov     [cci],r9d ;size
        invoke  SetConsoleCursorInfo,[hConsole],cci
        ret
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          msvcrt,'msvcrt.dll'

  import kernel,\
         GetStdHandle,'GetStdHandle',\
         SetConsoleCursorPosition,'SetConsoleCursorPosition',\
         SetConsoleCursorInfo,'SetConsoleCursorInfo',\
         GetConsoleScreenBufferInfo,'GetConsoleScreenBufferInfo',\
         ExitProcess,'ExitProcess',\
         Sleep,'Sleep'

  import msvcrt,\
         printf,'printf'

  hConsole dq ?
  iPercent dq ?
  iPrevCnt dq ?
  iPrevLoc dq ?
  iTmpMth1 dq ?
  iTmpMth2 dq ?
  iIncrmnt dq ?
  iCurLoc1 dq ?
  rCounter dq ?
  sbi:     rb 2+2+2+8+2 ;CONSOLE_SCREEN_BUFFER_INFO
  cci:     rb 4+4       ;CONSOLE_CURSOR_INFO
    

_________________
My updated idol Very Happy http://www.agner.org/optimize/
Post 04 Aug 2011, 09:25
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.