flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2 |
Author |
|
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. |
|||
![]() |
|
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. |
|||
![]() |
|
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!!! |
|||
![]() |
|
revolution 03 Aug 2011, 14:28
edfed wrote: you didn't consider the diffusion of code on the web. ![]() |
|||
![]() |
|
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.
|
|||
![]() |
|
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. ![]() ![]() Perhaps for this download progress bar it would be worth it.
|
||||||||||
![]() |
|
edfed 03 Aug 2011, 15:05
lol. insert A:
|
|||
![]() |
|
typedef 03 Aug 2011, 15:32
download the whole internet. lol
as George Bush would say "Internets" |
|||
![]() |
|
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. |
|||
![]() |
|
revolution 03 Aug 2011, 17:00
edfed wrote: is the 23,993,564,998MB value exact? |
|||
![]() |
|
edfed 03 Aug 2011, 17:02
if i run my apache server, we can add several megabytes to the count.
|
|||
![]() |
|
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. |
|||
![]() |
|
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 |
|||
![]() |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.