Author Topic: Steve's Video Tutorials  (Read 21349 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Video Tutorials
« Reply #15 on: September 23, 2019, 09:22:41 am »
And now for a technical question.  In the tutorial, the difference between file (hard disk) and _MEM objects is demonstrated, with the _MEM objects obviously (much) faster in access & processing than disk objects.  But if we exchanged the _MEM object with a "normal" variable / array, that would also be in memory and nowhere near the disk.  Is _MEM object processing still much faster than normal variable / array processing?  (I am, of course, sat at the back of the class with a pointed hat on, labelled "D").

It is — sometimes by upwards of 100+ times faster.

When you use _MEM, you go directly to the memory and read/write it.

When you use an array, or variable, your computer first has to look into a table and search for that variable.  Where is X stored in our lookup table?  Then, once it’s found, what’s it value?  What type of variable is it?  How big is it?  With an array, which element is it, in relation to the rest of the array?  The OS references all this information first, and then uses it to go to the memory address and retrieve the information for you.

Which is inherently faster:  Me telling you, “Get the third item off the top shelf,” or, “Fetch me the glibbersprocket,” if you have no idea what a glibbersprocket is, and I have to take time to describe it for you.  This is the difference between _MEM and variables/arrays. 

***************************

And don’t think of yourself as a dunce in the back of the class at all.  I’m happy folks are watching, taking interest, and asking questions.  That’s the whole point of doing the tutorials after all!  ;D

https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Steve's Video Tutorials
« Reply #16 on: September 23, 2019, 09:43:47 am »
Thanks Steve, I had imagined that this would be the case.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Steve's Video Tutorials
« Reply #17 on: September 23, 2019, 12:27:04 pm »
What a great tutorial. So very helpful for me on both Binary and _Mem. I am finding my screen is somewhat fuzzy, so the coding you are writing is hard to see but you explain it so well the fuzz makes sense. The old Peek and Poke seemed to be dangerous (in terms of remembering what address did what, and propensity to crash the program) so I did avoid using them, _Mem, I thought was going to be just as dangerous but maybe I do need to relook at this and your future videos. I'm working on an AI program (been at it for years). There's a lot of data to manipulate and multiple formulas. My focus has been on accuracy v's speed, needless to say its a slow moving AI.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Steve's Video Tutorials
« Reply #18 on: September 23, 2019, 12:46:08 pm »
Yep, the only thing faster than _MEM are BITWISE operators, the reason for this is the same as _MEM being faster than normal variable interactions. BITWISE operators are processed 'in house' within the processor, they never have to travel on the BUS to memory and back. they stay in the CPU, so you cut travel time nearly completely out. With today's BUS speeds the difference is getting smaller though. And when your working with variables the standard way there is a lot of back and forth between the CPU and RAM before the result is done.

You could think of it as needing a vegetable to eat,your property seen as the CPU, is faster to walk out to your garden and back than it is to take the bullet train to the store, seen as RAM, and back. its all a matter of distance traveled, and even at the speed of light(or 99% of it as electrons travel) it still takes time. As the standard use would be like Calling the store to make sure they had the vegetable, then calling a Cab, waiting on the Cab, going to the store buying the vegetable, then calling the Cab again, waiting on the Cab then getting home with the vegetable. the more travel and talking you can cut out the faster things happen.

_MEM gives you a heck of a lot more options though, as BITWISE operations are very limited being restricted to a single variable. Where as _MEM can act on a large group of variables. but that is getting into Apples vs Oranges territory there.

Granted a rather Simplified explanation, and may be a bit short here and there.
Granted after becoming radioactive I only have a half-life!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Steve's Video Tutorials
« Reply #19 on: September 23, 2019, 01:11:06 pm »
Steve and Cobalt, oh wow!  I'm looking forward to doing _MEM versions of my Crossword Generator (should produce new completed grids virtually instantly) and my Gravitational Simulation program (should produce a solar system from a collapsing random array of masses in a few minutes).

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Video Tutorials
« Reply #20 on: September 23, 2019, 03:49:14 pm »
Tutorial #1's finished code (as per the demo), placed here for ease of reference, in case anyone wants it:

QB64 window #1:
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 465, 32)
  2. _SCREENMOVE 121, -2
  3.  
  4. OPEN "tempbooger.txt" FOR BINARY AS #F
  5. junk$ = "Hello World"
  6. PUT #F, 1, junk$
  7.  
  8. temp$ = SPACE$(5)
  9. GET #F, 1, temp$
  10. PRINT temp$
  11.  
  12. GET #F, 7, temp$
  13. PRINT temp$
  14.  

Compared to QB64 window #2:
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 465, 32)
  2. _SCREENMOVE 921, -2
  3.  
  4. M = _MEMNEW(10000)
  5. PRINT M.SIZE
  6. junk$ = "Hello World"
  7. _MEMPUT M, M.OFFSET, junk$
  8.  
  9. temp$ = SPACE$(5)
  10. _MEMGET M, M.OFFSET, temp$
  11. PRINT temp$
  12.  
  13. _MEMGET M, M.OFFSET + 6, temp$
  14. PRINT temp$
  15.  
  16.  

As you can hopefully see by comparing the two programs closely against each other, their syntax and usage is almost exactly the same.  If you can read and write to a binary file on your hard drive, you can read and write to memory inside your program.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Video Tutorials
« Reply #21 on: September 23, 2019, 04:43:28 pm »
Tutorial #2 is now up on youtube (find the link via the quick reference area of the first post in this topic), and here's the finished code which we end up producing from it:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 380, 32)
  2.  
  3. PRINT "Steve's _MEM Tutorial lesson 2: Little Endian and Big Endian"
  4.  
  5. 'Little Endian stores values from right to left.
  6. 'Big Endian stores values from left to right.
  7.  
  8. 'Let's take the value Ninty-One, as an example.
  9. 'In English (and most other languages I know), we would write that value as "91".
  10. 'The 9 here represents the ten's position, and the 1 represents the one's position.
  11.  
  12. 'But what if we were wringing in Arabic, or Hebrew?  Those languages read from
  13. 'right to left.  I'm no expert with either language -- in fact, I don't know
  14. 'squat of either -- but wouldn't they write the value as "19"?
  15. 'The 9 would still represent the ten's position, and the 1 would still represent
  16. 'the one's position, but we'd write them from right to left, instead of from left
  17. 'to right.
  18.  
  19. 'This is basically the difference in Little Endian values and Big Endian values.
  20. 'Little Endian stores values from right to left.
  21. 'Big Endian stores values from left to right.
  22.  
  23. m = _MEM(x)
  24.  
  25. _MEMPUT m, m.OFFSET, 1 AS INTEGER
  26.  
  27. x = 0
  28.  
  29. _MEMPUT m, m.OFFSET, 1 AS _UNSIGNED _BYTE
  30.  
  31. x = 0
  32.  
  33. _MEMPUT m, m.OFFSET + 1, 1 AS _UNSIGNED _BYTE
  34.  
  35. PRINT "Hello World"
  36. m = _MEMIMAGE(0) '0 is the display screen.
  37.     IF _MEMGET(m, m.OFFSET + o, _UNSIGNED LONG) = _RGBA32(255, 255, 255, 255) THEN
  38.         _MEMPUT m, m.OFFSET + o, 256 AS _UNSIGNED _BYTE
  39.     END IF
  40.     o = o + 4
  41. LOOP UNTIL o >= m.SIZE - 4
  42. 'White = "&H" FF,FF,FF,FF  AA, RR, GG, BB.
  43. 'It's stored LITTLE ENDIAN values.
  44. 'Blue, Green, Red, Alpha
  45.  
« Last Edit: April 02, 2020, 10:28:55 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Steve's Video Tutorials
« Reply #22 on: September 23, 2019, 07:03:54 pm »
Great job with image quality this time.

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Steve's Video Tutorials
« Reply #23 on: September 24, 2019, 10:20:03 am »
Quality is great, topic fascinating.
Before I start messing around with my rather large program, how do I determine how much memory is actually available before blocking off a section?
Also, I'm thinking, the use of memory is not necessarily to "store" data for the duration of the program run, seems the idea would be to block off what you need, use it for fast calculations or temporary storage / retrieval / update of data and then Free the Memory block.  So is there a way to determine exactly how much memory size might be needed for different types of tasks/usage of the memory block set aside?
Is the size of the memory block automatically calculated for an array by use of LEN?
I did a search of the wiki but not of the forum past topics, so I'm sorry Steve if these question have been previously addressed.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Steve's Video Tutorials
« Reply #24 on: September 24, 2019, 10:42:49 am »
Before I start messing around with my rather large program, how do I determine how much memory is actually available before blocking off a section?

the answer to that question is the amount of available memory on your machine, and whether or not you are using 32bit or 64bit QB64.

So is there a way to determine exactly how much memory size might be needed for different types of tasks/usage of the memory block set aside?

to answer that, you have to know the sizes of what you want to be working with, _BYTE=1, INTEGER=2, LONG\SINGLE=4, DOUBLE\INTEGER64=8, and STRINGs are 1*len of string.
for more types go into the wiki under Variable Types: http://www.qb64.org/wiki/Variable_Types
Granted after becoming radioactive I only have a half-life!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Video Tutorials
« Reply #25 on: September 24, 2019, 11:07:43 am »
Quality is great, topic fascinating.
Before I start messing around with my rather large program, how do I determine how much memory is actually available before blocking off a section?
Also, I'm thinking, the use of memory is not necessarily to "store" data for the duration of the program run, seems the idea would be to block off what you need, use it for fast calculations or temporary storage / retrieval / update of data and then Free the Memory block.  So is there a way to determine exactly how much memory size might be needed for different types of tasks/usage of the memory block set aside?
Is the size of the memory block automatically calculated for an array by use of LEN?
I did a search of the wiki but not of the forum past topics, so I'm sorry Steve if these question have been previously addressed.

Available memory depends on your OS and PC. 

If you’re using 32-bit versions of QB64, you’re going to be capped out at about 1.5GB total memory usage in your programs.  (2GB is the true 32-bit cap due to limits with using LONG values for offsets, but your OS reserves some space for its needs.  Once you start getting at the 1.5 GB memory mark, on a 32-bit OS, your program is walking dangerously close to crashing.)

For 64-bit systems, you can use as much memory as your system has plus allocated swap space.  The largest program I’ve ever ran used about 8-9GB of memory, as it had a huge database associated with it and loaded the WHOLE thing into memory at once, to sort/pack/compress it — and it ran with no issues at all on my home PC (with 32GB RAM), but was impossible to run on my laptop (8GB RAM).

For arrays, you can DIM them as you normally do, and then just point a MEM variable to where they’re already at in memory.  (Lesson 3 should cover this topic, I think, but it’ll probably be a few days before I get around to it.)

Basically:

DIM MyArray(1000) AS ArrayType
DIM M AS _MEM
M = _MEM(ARRAY())

And with the above, your MEM variable is pointing to your MyArray in memory.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Steve's Video Tutorials
« Reply #26 on: September 24, 2019, 11:43:14 am »
Hi Cobalt - So I have 8 GB of Ram, 64 bit os. So I believe Steve said some memory is already protected by windows and my program itself must be taking up some memory. Also as the years go by and the program grows, more memory usage is expected. I recall in the old days there was a Free Memory command or something like that, which did not Free UP memory but gave you the amount of Free Memory available. Would QB64 have something similar?

I did review the Variable_Types in the wiki and my confusion in determining the how much memory size is specifically how to calculate it. For example, if the variable is LONG, would the memory be set aside as ' M = _MemNew (2,147,483,647)? or if M is a REDIM array which starts out at hold 10 elements = 10 x 4 for long and therefore I would start to set aside M=_MemNew(40) and if that array grows by 10 new element each loop (20 x 4),then M now is M = _MemNew(80). So would if I have 8 gigs, setting the max and then freeing the max would be the way to go??


 

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Steve's Video Tutorials
« Reply #27 on: September 24, 2019, 11:54:11 am »
REDIM arrays are a little tricky, as they free MEM handles automatically when you resize them, but all you have to do is make certain to point them at the resized array after.

REDIM MyArray(1000) AS LONG ‘4000 bytes in memory + a little overhead
DIM M AS _MEM
M = _MEM(MyArray()) ‘point to the array’s memory. No need to set aside any more for use.

REDIM _PRESERVE MyArray(10000) AS LONG ‘expand to 40000 bytes in memory
M = _MEM(MyArray()) ‘make certain to point to wherever the resized array is now at in memory.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Steve's Video Tutorials
« Reply #28 on: September 24, 2019, 12:12:46 pm »
Oh, thanks Steve

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Steve's Video Tutorials
« Reply #29 on: September 24, 2019, 01:16:45 pm »
For example, if the variable is LONG, would the memory be set aside as ' M = _MemNew (2,147,483,647)? or if M is a REDIM array which

No, all you need to worry about is how many bytes are needed for each type, a LONG is 4 bytes in memory, not the max value each variable type can contain, LONG - max signed value= 2,147,483,647.
so
M = _MemNew (4)
would hold: 1-LONG, or 2-INTEGERs, or 4 _BYTEs.

If your machine has ~8gigs of ram I would use a conservative approach and say you could allocate 6.25 gigs max to a program, leaves memory for your OS, QB64, and other background programs that might need an amount of ram too.

M = _MemNew (6250000000) 'technically 6710886400 is 6.25GB
and that would allocate as much memory as I would conservative consider safe from crashing your program on a 64bit OS using 64bit QB64.

And Steve nails the Array part of your questions. And I think Steve's explanation of the rest is most likely better than anyway I could put it.
Granted after becoming radioactive I only have a half-life!