Author |
Topic: Instruction speed (Read 655 times) |
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Instruction speed
« Thread started on: Jan 22nd, 2016, 5:30pm » |
|
Does anyone know what the difference is between basic and assembler speed? Ie if I used the instruction X+=1 how long would it take compared to [add eax,1]? Working on 3D graphics and just wondered what the time saving would be.
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: Instruction speed
« Reply #1 on: Jan 28th, 2016, 3:35pm » |
|
Hi Ric,
Probably a lot (an order of magnitude?) - but I suspect it wouldn't be worth the overhead of calling an assembler routine for one instruction!
You might find that some things are so fast that it's not worth it - for example, whole-array operations can speed things up dramatically if used cleverly.
The other thing to think about is the relative time spent doing whatever calculations you are doing and the time spent doing the plotting. If you are doing the latter in BB4W graphics commands then it is likely the time spent doing the calculations is negligible - on the other hand, if you are passing all the actual plotting to D3D, for example, it may be worth speeding up your calculations.
David Williams would be a good person to comment on this, since he's done a lot with fancy graphics plotting...
...or you could email Richard Russell, of course - he's a great advocate of the assembler.
Hope that's useful.
D
|
|
Logged
|
|
|
|
ady
Junior Member
member is offline


Posts: 55
|
 |
Re: Instruction speed
« Reply #2 on: Jan 30th, 2016, 01:59am » |
|
Assembler is miles faster, especially if integers are being used. Using C for calculations can give you a reasonable "assembler" comparison against basic when things get more complicated
As mentioned though, clever basic programming can save an awful lot of coding time while producing a perfectly reasonable speed of execution One of my favourites is Richards sudoko solver
|
|
Logged
|
|
|
|
Zaphod
Guest
|
 |
Re: Instruction speed
« Reply #3 on: Jan 30th, 2016, 02:45am » |
|
Quote:One of my favourites is Richards sudoko solver |
|
Yes that is a pretty amazing piece of code, clever thinking and great use of recursion. This was unnecessarily obscure though; Code:IF P% P% = LOGP%/LOG2+1.5 since LOG2 is a constant I am sure that using the LOG function for that slows it down just a bit. Just to show how much you can do in a single line with some thought here are the comments I added to my version once I figured it out... Code: IF P% P% = LOGP%/LOG2+1.5
REM convert from bit position to number. Uses log theory to convert from a number to the base 2 to a number base 10
REM say P% was %10000 or 2^5 this needs to be converted to 5. Log to the base 2 would give us that.
REM but we have log to base 10 function available. So Log N to base 2 = log N to base 10 / log 2 to base 10
REM The +1.5 is 0.5 to avoid a rounding error as we place the result in to an integer, and 1 to get the right ASCII code below.
If the original questioner has not already mastered the Profiler Utility I would recommend that to find out where the program is spending all its time and then adjusting only those parts that are needed. And as Richard often showed rearranging the problem that you are trying to solve sometimes makes it many times as fast.
Z
|
|
Logged
|
|
|
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Re: Instruction speed
« Reply #4 on: Feb 2nd, 2016, 07:36am » |
|
Thanks guys, I am trying to produce realistic 3d graphics for gaming. The theory is quite easy and the number crunching laborious, but it is the graphics speed which is slow. In essence I need to be able to update every screen pixel about 30 times a second, if this can be done in basic I would be happy to talk to anybody that can offer insight. But my initial thoughts are to write assembler routines for this. And the question about speed was to see if it was worth pursuing or knocking it on the head. The latter is not an option really as I have the bit between my teeth and failure is not an option  Ric
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Re: Instruction speed
« Reply #5 on: Feb 2nd, 2016, 09:11am » |
|
Just a little aside, after changing the DIB section using assembler, the screen has to be *REFRESHed to display changes. Is there a way to enable this to be done automatically and/or done from within the assembler routine?
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: Instruction speed
« Reply #6 on: Feb 2nd, 2016, 4:42pm » |
|
Hi Ric,
So you are already doing the most important thing: writing directly to a DIBSection rather than using BB4W drawing commands...
To answer your supplementary question, you can replace the *REFRESH with a call to "InvalidateRect" - either in BB4W using the SYS command, or in your assembler using call (see the section on "calling the Windows API" in the Assembler section of the manual).
The other comment I'd make is to ask whether you really need to redraw all the pixels every frame, and if so, whether many of them will be different. For example, if you can keep a "background image" in a separate bitmap and use the Windows Blitting functions to copy it to your working buffer, it will be MUCH faster than changing each point individually - and you could offset it, so that you could have a moving background, if necessary (and if your background image is bigger than the view).
If you actually only need to update part of the screen, using InvalidateRect with specific coordinates will be substantially faster than updating the whole screen each time.
Are you going to treat us to a demo of this project sometime?

D
|
|
Logged
|
|
|
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Re: Instruction speed
« Reply #7 on: Feb 3rd, 2016, 8:35pm » |
|
;D ;D ;D
Thanks DDRM.
I can only think of being able to redraw (repixel) every time because the screen will be in 3D depth perception view which will change constantly. Ho Hum!!
The demo is a long way off because there are a lot of aspects of the 3D gaming that I have yet to learn, (until recently it has been 30 years since I programmed a computer), and as I am only able to get max 1/2 to 1 hour a night in, it takes more time than I would wish. ;) But I will post samples of the code as I learn it for anyone who is interested in 3D development. Code:
I have run the following program with the "InvalidateRect" command both present and missing.
With the command present the Assembler version refreshes 376 times a second and the Basic version 1.4 times a second.
But if the command is missing the Assembler version refreshes 622 times per second and the Basic version again 1.4 per second.
Inference the Assembler runs approx. 450 times faster than the Basic version, not quite the facto I was expecting!
10 VDU 23,22,1346;674;16,16,16,0 20 30 REM *** DO NOT PRESS ESCAPE TO EXIT ASSEMBLER VERSION *** 40 50 DIM code% NOTEND AND 2047, code% 6143 60 70 80 90 CLS 100 DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, ClrUsed%, ClrImportant%} 110 DIM bmi{Header{} = BITMAPINFOHEADER{}} 120 bmi.Header.Size% = DIM(BITMAPINFOHEADER{}) 130 bmi.Header.Width% = 1346 140 bmi.Header.Height% = 674 150 bmi.Header.Planes.l& = 1 160 bmi.Header.BitCount.l& = 32 170 180 SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^bits%, 0, 0 TO hbitmap% 190 IF hbitmap%=0 ERROR 100, "Couldn't create DIBSection" 200 210 SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm% 220 SYS "DeleteObject", oldhbm% 230 SYS "InvalidateRect", @hwnd%, 0, 0 240 250 FOR I% = 0 TO 2 STEP 2 260 P% = code% 270 [ 280 OPT I% 290 .start 300 mov eax, &00 310 mov edx, [^bits%] 320 mov ebx, edx 330 add edx, 3628812 340 .loop 350 mov [edx], eax 360 sub edx, 4 370 cmp edx, ebx 380 jne loop 390 add edx, 3628812 400 add eax, 1 410 push eax 420 push ebx 430 push edx 440 push 0 450 push 0 460 push @hwnd% 470 call "InvalidateRect" 480 pop edx 490 pop ebx 500 pop eax 510 cmp eax, &00010000 520 jne loop 530 ret 540 550 ] 560 570 NEXT I% 580 590 INPUT "RUN (B)asic or (A)ssembler ";choice$ 600 IF choice$="A" OR choice$="a" THEN 640 610 IF choice$="B" OR choice$="b" THEN 710 620 GOTO 590 630 640 TIME=0 650 CALL start 660 PRINT TIME 670 SYS "InvalidateRect",@hwnd%,0,0 680 690 GOTO 590 700 710 TIME=0 720 A%=0 730 D%=bits% 740 B%=D% 750 D%+=3628812 760 ?D%=A% 770 D%-=4 780 IF D%<>B% THEN 760 790 D%+=3628812 800 A%+=1 810 SYS "InvalidateRect",@hwnd%,0,0 820 IF A%<>256 THEN 760 830 PRINT TIME 840 850 GOTO 590
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Re: Instruction speed
« Reply #8 on: Feb 3rd, 2016, 8:37pm » |
|
[code][ 10 VDU 23,22,1346;674;16,16,16,0 20 30 REM *** DO NOT PRESS ESCAPE TO EXIT ASSEMBLER VERSION *** 40 50 DIM code% NOTEND AND 2047, code% 6143 60 70 80 90 CLS 100 DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, ClrUsed%, ClrImportant%} 110 DIM bmi{Header{} = BITMAPINFOHEADER{}} 120 bmi.Header.Size% = DIM(BITMAPINFOHEADER{}) 130 bmi.Header.Width% = 1346 140 bmi.Header.Height% = 674 150 bmi.Header.Planes.l& = 1 160 bmi.Header.BitCount.l& = 32 170 180 SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^bits%, 0, 0 TO hbitmap% 190 IF hbitmap%=0 ERROR 100, "Couldn't create DIBSection" 200 210 SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm% 220 SYS "DeleteObject", oldhbm% 230 SYS "InvalidateRect", @hwnd%, 0, 0 240 250 FOR I% = 0 TO 2 STEP 2 260 P% = code% 270 [ 280 OPT I% 290 .start 300 mov eax, &00 310 mov edx, [^bits%] 320 mov ebx, edx 330 add edx, 3628812 340 .loop 350 mov [edx], eax 360 sub edx, 4 370 cmp edx, ebx 380 jne loop 390 add edx, 3628812 400 add eax, 1 410 push eax 420 push ebx 430 push edx 440 push 0 450 push 0 460 push @hwnd% 470 call "InvalidateRect" 480 pop edx 490 pop ebx 500 pop eax 510 cmp eax, &00010000 520 jne loop 530 ret 540 550 ] 560 570 NEXT I% 580 590 INPUT "RUN (B)asic or (A)ssembler ";choice$ 600 IF choice$="A" OR choice$="a" THEN 640 610 IF choice$="B" OR choice$="b" THEN 710 620 GOTO 590 630 640 TIME=0 650 CALL start 660 PRINT TIME 670 SYS "InvalidateRect",@hwnd%,0,0 680 690 GOTO 590 700 710 TIME=0 720 A%=0 730 D%=bits% 740 B%=D% 750 D%+=3628812 760 ?D%=A% 770 D%-=4 780 IF D%<>B% THEN 760 790 D%+=3628812 800 A%+=1 810 SYS "InvalidateRect",@hwnd%,0,0 820 IF A%<>256 THEN 760 830 PRINT TIME 840 850 GOTO 590 ]
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Re: Instruction speed
« Reply #9 on: Feb 3rd, 2016, 8:38pm » |
|
How do you insert code?
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: Instruction speed
« Reply #10 on: Feb 8th, 2016, 10:45am » |
|
Place code between code tags. [.code] PRINT "Test" [./code]
Remove the dots in [.code][./code] Code:
Svein
|
|
Logged
|
|
|
|
DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Re: Instruction speed
« Reply #11 on: Feb 8th, 2016, 12:03pm » |
|
Hi Ric,
Thanks for the demo(s) - one of which appears to have disappeared again!
The assembler re-writing is certainly spectacularly fast, even if the display isn't that exciting yet... 
...maybe I need to revisit my need to get to grips with some simple assembler processing.
The cube demo (which appeared but now seems to have disappeared) is impressive - but if that is the kind of thing you want to do, can I encourage you to think about using Direct 3D via the library? If you look in the samples that came with BB4W (under graphics) you'll find a very simple example called pyramid.bbc,which is not dissimilar to your cube but runs more smoothly. D3D is nice, because you get rotation, scaling etc of the object "for free", and you can also move the viewpoint - very powerful if you are thinking of a game where you move around.
That relies on a pre-defined file for the shape, but it is possible to generate the buffer on the fly - if you look at the proto-flightsim I posted here:
http://bb4w.conforums.com/index.cgi?board=graphics&action=display&num=1439311250
I make a map, generate a D3D vertex buffer on the fly, and render it. There is also some code to control lighting, which you might find useful.
There's been quite a lot of debate here about different D3D models - the one that comes with BB4W uses D3D8, because the support files are freely available, though Richard also produced a D3D9 equivalent, as well as some files to map all the methods for different parts of it (sorry, my nomenclature is all over the place..). Others have argued for D3D11 - but that works rather differently, so would take some getting used to, while D3D9 is pretty like D3D8.
Best wishes,
D
|
« Last Edit: Feb 8th, 2016, 12:06pm by DDRM » |
Logged
|
|
|
|
Ric
Full Member
member is offline


Gender: 
Posts: 136
|
 |
Re: Instruction speed
« Reply #12 on: Feb 8th, 2016, 9:51pm » |
|
DDRM, you are right about the speed. It is very impressive. I will look at D3D, but the challenge I set my self was to produce a 3D game in asm. I am much further on than the demo would suggest, writing small bits of code to perform the tasks required. I will move the chat to 3D gaming project as only a very small percentage of the code is in asm at the moment (that challenge has yet to come!). I am experimenting in Basic first which is why the images are jerky. But one day I will succeed and all the routines will be in asm
|
|
Logged
|
It's always possible, but not necessarily how you first thought. Chin up and try again.
|
|
|
|