Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Is It Arrays, Reading Bytes, or Dot that is slow?

Author
Message
Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 2nd Apr 2011 10:21 Edited at: 3rd Apr 2011 07:55
So i have recently come up with my own rather undeveloped, proprietary image format. For quick prototyping i am using DBPro to make image converters and readers, now while DBPro is great at making these programs quickly, the programs dont read the image quickly enough. The old one i made took about 15 seconds to load a 1024 by 768 image, which would load in GIMP in about 2 seconds. Then i realized my format currently doesnt use any compression methods so i did a test. In DBPro i made a program that would read everything in the file and it read the whole thing in around 1 second. Now what my old image reader would do is it would read the byte and draw it to the screen (its not too proprietary yet) So i did a test where it had to draw a bunch of pixels with the dot command to the screen. That too in a 1024 by 768 run was very fast. Not being able to figure it out i decided to try a new method that loads all the bytes into a giant array then draws the contents of the array to the screen with the dot command. I did a test on writing to and reading from the array, and those were extremely fast too. I combined them all together and there Mr. Fifteen Seconds was...

Why is this?

Either way, all help is what you could call 'appreciated!'

I drew my avatar pixel by pixel in GIMP
BatVink
Moderator
23
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 2nd Apr 2011 12:44 Edited at: 2nd Apr 2011 12:47
DOT is extremely slow, you should use one of the alternatives out there, or use memblocks to manipulate your image. Advanced 2D by Diggsey (in program announcements) is very fast. You should also lock the target, which speeds things up even more.

IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 2nd Apr 2011 13:32
Arrays: Every time you access an array, it checks to make sure you aren't accessing out of bounds. Use a memblock instead.

Reading bytes: A switch to the OS for every read. Either read the whole file into a memblock at the start and access the data that way, or use my file plug-in which buffers access to the file.

Dot: Gains access to the display memory each time, writes the value, then releases access. As BatVink said.

kaedroho
18
Years of Service
User Offline
Joined: 21st Aug 2007
Location: Oxford,UK
Posted: 2nd Apr 2011 18:37
Quote: "Arrays: Every time you access an array, it checks to make sure you aren't accessing out of bounds. Use a memblock instead."


Don't memblocks also check that your not accessing out of bounds?

Your signature has been erased by a mod please reduce it to no larger than 600 x 120.
Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 2nd Apr 2011 20:11
Thanks guys, i will try all these!

DBD79
BatVink
Moderator
23
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 2nd Apr 2011 20:31
Quote: "Don't memblocks also check that your not accessing out of bounds?"


They do, I recall getting out of bounds error messages. Maybe it's a more efficient check on memblocks.

I know that memblocks are a lot faster to access than arrays. I changed my spline generating routine from an array of data to the same data in a memblock. The code was more complex, but the speed was a damn site faster. This was the only way I could realistically edit my spline roads in realtime.

Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 2nd Apr 2011 20:53
So i did a test on the a2dot command and to draw my whole screen took one second longer than the regular dot command I used a timer and everything to time it...

DBD79
Mr Kohlenstoff
20
Years of Service
User Offline
Joined: 7th Jun 2006
Location: Germany
Posted: 2nd Apr 2011 20:59 Edited at: 2nd Apr 2011 21:00
Quote: "I know that memblocks are a lot faster to access than arrays. "


Aren't DBP arrays basically linked lists? And memblocks on the other hand are, well, memory blocks, of static position and size. But I remember that when I tested it a few weeks ago, the speed improvements when using memblocks were lying between -20 and +50%, depending on the way I accessed the data. But that was DBP 6.6, there might be differences in the more up to date versions.
Oh, and another thing I remember is that reading/writing dwords is always faster than reading/writing four bytes. So when it comes to image manipulation using memblocks, it's faster to work with complete color dwords instead of single color channels.

Anyway, as Batvink and IanM already explained sufficiently, the dot command is comparably slow (line and circle as well, for that matter, but that seems to be depending on the machine your program is running on) and probably causes the low speed.


DBD79: What about some Code? Oh, and I like your signature. It's so positive.

Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 2nd Apr 2011 21:10 Edited at: 2nd Apr 2011 21:15
I know they said the dot command was slow. I said the a2dot command was slower. Here is the code that proves it:



Quote: "It's so positive."
Haha indeed, thanks!

I was also wondering if anyone would be will to show me what code i would need to load a file into a memblock? I have very limited knowledge on memblocks...

DBD79
Mr Kohlenstoff
20
Years of Service
User Offline
Joined: 7th Jun 2006
Location: Germany
Posted: 2nd Apr 2011 21:42
Something like this



or alternatively 'make memblock from file' as far as I remember. At least that's the way I usually do it.

Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 2nd Apr 2011 21:47
Thanks! I will try to 'make image from memblock' to see if that is any faster...

DBD79
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 2nd Apr 2011 22:13
Quote: "Aren't DBP arrays basically linked lists?"

No, internally they are arrays of pointers to data, adding an extra level of indirection to arrays.

Quote: "Don't memblocks also check that your not accessing out of bounds?"

Memblocks do check their bounds, but IIRC, it's a simpler check than arrays have, as memblocks don't have multiple dimensions to worry about.

Part of the difference is also in how the runtime accesses the data. For instance if you were reading through a memblock of dwords, you'd simply increment your index by 4 each time between reads. The runtime will carry out a bounds check, then take the memblock pointer, add your index and read the data.

If you access an array of dwords (assuming a 1D array here), you'd increment your index by 1, then the runtime will take your index, bounds check it, carry out a multiplication by 4 for you (to access the correct pointer in the array), then read the pointer and use that to read the data.

In addition, memblocks are contiguous addressable memory, while arrays can have their data dotted about in memory, depending on how you manipulate the array data.

It can go the other way too though. Simulating a multi-dimensional array with a memblock could easily cause you to carry out more operations in a less efficient manner than array access.

Quote: "I was also wondering if anyone would be will to show me what code i would need to load a file into a memblock?"

It's easiest (and possibly fastest - test it) with my bank plug-in:


Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 2nd Apr 2011 22:57
I'll try that! So does anyone know why a2Dot is so slow? You guys told me it would be faster than the regular dot command

DBD79
BatVink
Moderator
23
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 2nd Apr 2011 23:58 Edited at: 2nd Apr 2011 23:59
I think Diggsey may have a problem with a2Dot. All of his other commands are much better.

Try this, I was putting together a more accurate test and it highlights a few things:



1. a2dot is definitely slower
2. a2dot doesn't work with LOCK PIXELS

but more importantly

DOT is about 30 times faster when you lock the pixels as recommended earlier.


If you want to experiment with memblocks, I can recommend a very good tutorial

http://www.thegamecreators.com/pages/newsletters/newsletter_issue_32.html#9

Neuro Fuzzy
19
Years of Service
User Offline
Joined: 11th Jun 2007
Location:
Posted: 3rd Apr 2011 00:02
cloggy's DLL/d3dfunc is really fast...

http://www.dbdepot.co.uk/d3dfunc.html

Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 3rd Apr 2011 03:37
With the lock pixels it is 2.167 times faster!
Quote: "as recommended earlier"
Haha you said lock target, i didnt know what that was... Thanks for the link!

I will check out the DLL, thanks!

DBD79
Kevin Picone
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 3rd Apr 2011 04:17 Edited at: 3rd Apr 2011 04:19
Since the end For/Next loop evaluates the end expression each iteration in Dbpro, it's worth pre-computing such values outside of the loops.

Just quickly, so this



Could be expressed as



A simple rearrangement, but you're saving a call to Screen Width() every pixel drawn. So for a screen size 1024*768 that's a lot of call overhead wasted.

Might be able to unroll the inner loops to further improve this, as manually adding/bumping the X offset, might be quicker than the normal FOR/NEXT loop over head. (which is likely, but not a guarantee )


So perhaps,



Note: This assumes the width is an evenly divisiable by 4

The best option would probably be remove the DOT and write directly into the surface. So lock the surface, grab the address and pitch and write each 32bit colour value into the buffer and bump pointer directly

(pseudo DBpro styled code)



Just go to careful not to run off the edges of the image buffer, which means certain crash. Also need to be sure that the buffer is indeed 32bits before hammering on it. If it's not, the the inner loops would need be to customized for 16/24 bit situations.

Dark Java Dude 64
Community Leader
15
Years of Service
User Offline
Joined: 21st Sep 2010
Location: Neither here nor there nor anywhere
Posted: 3rd Apr 2011 07:48
I see, those are awesome examples, thanks!

DBD79

Login to post a reply

Server time is: 2026-07-11 14:56:31
Your offset time is: 2026-07-11 14:56:31