HP Forums

Full Version: HP 49G / HP 50G memory
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
For my HP 50G and even my HP 49G that I still use I always have this question about memory storage. I know that flash memory is safer as it won't be lost in case of memory lost. Is there any advantage of port 0 or port 1 over port 2 ?

Thanks
(11-15-2017 06:54 PM)groskwik Wrote: [ -> ]For my HP 50G and even my HP 49G that I still use I always have this question about memory storage. I know that flash memory is safer as it won't be lost in case of memory lost. Is there any advantage of port 0 or port 1 over port 2 ?

Thanks

Programs and objects stored in port 0 are accessed and executed directly, while objects in ports 1 and 2 require the calculator O/S to perform bank switching (and possibly copying of the objects to temporary memory as well). Generally speaking, this means that executing code from port 0 will perform better than the same code stored in port 1 or 2.

The delay of a single port 1/2 object being accessed is negligible, but if you are executing a program repeatedly, say in a loop, the accumulated effect is noticeable.
Port 0 resides in SRAM and programs run directly off of SRAM (presumably the first two 128KB banks of the 512KB chip). Port 1 is the remaining SRAM. Both of these are equally fast.

Port 2 is FLASH, and programs from here must first be copied to user memory -- usually the same place where Port 0 resides. Then it is run from there. So the only speed hit, really, is the copy phase prior to execution. You would only notice this when running really huge apps (and even then, I am not sure you would perceive much of a difference unless your programs repeatedly call other programs in Port 2).
When a library is stored in a high port (not main RAM), every time a command in the library is called, ONLY THAT COMMAND gets copied to RAM, then it is run there. The entire library is NOT copied to RAM. Library authors must be aware of one potential danger (caused by this scheme) which can even wipe out all your memory.

The problem only occurs when a library author includes multiple Saturn code objects in the source code of a library, AND includes a Saturn jump (e.g. a GOVLNG) which jumps directly from one library command into a Code object in another command. It's tempting to do this, since it can avoid repeating code, but it will make the library crash if run from a high port, because the intended target of the jump will not have been copied to RAM, and the jump will land on unpredictable contents of RAM.

This is one of the reasons that some libraries which run fine in RAM ports fail to run in higher ports.
Interesting Joe, thanks!
(11-17-2017 04:14 PM)Han Wrote: [ -> ]Port 0 resides in SRAM and programs run directly off of SRAM (presumably the first two 128KB banks of the 512KB chip). Port 1 is the remaining SRAM. Both of these are equally fast.

But there's still some overhead required for port 1 that isn't for port 0, so in practical use they aren't really equally fast. I realize that I'm being very picky here, but the incremental difference can be seen for repeated operations:
Code:
\<<
  @ store a simple object in each port 0-2
  "ABCDEFG"
  DUP :0:tempstr STO
  DUP :1:tempstr STO
  :2:tempstr STO

  @ retrieve the object 500 times from port 0
  TICKS
  1 500 START
    :0:tempstr RCL DROP
  NEXT
  TICKS SWAP - B\->R 8192 /
  "port0" \->TAG

  @ retrieve the object 500 times from port 1
  TICKS
  1 500 START
    :1:tempstr RCL DROP
  NEXT
  TICKS SWAP - B\->R 8192 /
  "port1" \->TAG

  @ retrieve the object 500 times from port 2
  TICKS
  1 500 START
    :2:tempstr RCL DROP
  NEXT
  TICKS SWAP - B\->R 8192 /
  "port2" \->TAG

  @ purge the objects
  { :0:tempstr :1:tempstr :2:tempstr } PURGE
\>>
(Disclaimer: the above is meant to be more illustrative than efficient Smile)

Note that each of the loops is exactly the same except for the port designation of the object it recalls. The tagged numbers in the result are the times (in seconds) for each of the retrieval loops.

Results on my 50g:
port0: 1.993
port1: 2.992
port2: 4.046

Results on my 49g:
port0: 3.700
port1: 4.550
port2: 5.738


(11-18-2017 05:46 AM)Joe Horn Wrote: [ -> ]When a library is stored in a high port (not main RAM), every time a command in the library is called, ONLY THAT COMMAND gets copied to RAM, then it is run there. The entire library is NOT copied to RAM. Library authors must be aware of one potential danger (caused by this scheme) which can even wipe out all your memory.
...

The advantage of the above design is more efficient use of available memory, of course. One way of dealing with that is to cache subroutines where needed into locals. Yes, there's more setup required when accessing them that way, but in my experience it's still faster than repeatedly accessing library entries when the library is stored in port 1 or 2.
One incidental thing I've noticed about storing and running libraries I've written in Port 1 vs. other ports is that there is often a bit of flickering “snow” on the screen at times if they run from Port 1, whereas I don't notice this effect if they run from Port 2 or Port 0.

Oddly enough, despite what was said above, it seems that in some of my informal tests, programs from libraries stored in Port 1 appear to run slightly slower on my 50g than from Port 2. For instance, I tried executing a loop that repeatedly called a short UserRPL program I had stored in a library; with the library in Port 1, I got fewer average executions per second than in Port 2, and in Port 2 I got fewer executions per second than I got with the library in Port 0. However, the increase in performance from Port 1 to Port 2, or from Port 2 to Port 0, was only on the order of around 3 to 5 percent or so.

However, in my case these were quick tests that I didn't perform too terribly rigorously, so it's possible there are several variables I didn't account for.
(11-19-2017 01:37 AM)TravisE Wrote: [ -> ]Oddly enough, despite what was said above, it seems that in some of my informal tests, programs from libraries stored in Port 1 appear to run slightly slower on my 50g than from Port 2. For instance, I tried executing a loop that repeatedly called a short UserRPL program I had stored in a library; with the library in Port 1, I got fewer average executions per second than in Port 2, and in Port 2 I got fewer executions per second than I got with the library in Port 0. However, the increase in performance from Port 1 to Port 2, or from Port 2 to Port 0, was only on the order of around 3 to 5 percent or so.

FWIW I was actually surprised in my above test that port 1 came out ahead of port 2, because I've experienced the same thing as you when testing real applications. I don't have any concrete data to back it up, though. Just recollections of previous tests.

I did try adjusting the above program to use a larger temporary object, and that brought the port 1 & 2 timings much closer together (but port 2 was still the slowest). Purely speculation on my part, but I'm wondering if something slows down port 1 further when the targeted object is executable code (or objects in a library).

Whatever the true causes may be, I simply don't use port 1 for anything where performance is an issue. I use port 2 for the majority of my library storage, and port 0 is reserved mostly for development and testing.
Reference URL's