Host Engineering Forum

General Category => Do-more CPUs and Do-more Designer Software => Topic started by: johnr on February 04, 2020, 09:42:29 AM

Title: MEMCOPY and Partial Structures
Post by: johnr on February 04, 2020, 09:42:29 AM
I'm working through my first major Do-More migration from DL, and I seem to have come up against the limit that MEMCOPY only copies entire structures. 

I was really hoping I'd be able to copy valid ranges of bytes in and out of some user data types I'm using.  It would greatly help manage the legacy mixed-type V-table data blocks that I setup in DL many years ago, reducing a whole bunch of messy address translation issues.

I noticed a thread from 2017 where this MEMCOPY limit was confirmed, there was some mention that this might be addressed at some point.  Is there now a way to do this that I'm missing, or is it still in the plans to add to DMD at some point?  Thanks.
Title: Re: MEMCOPY and Partial Structures
Post by: BobO on February 04, 2020, 10:28:21 AM
I'm working through my first major Do-More migration from DL, and I seem to have come up against the limit that MEMCOPY only copies entire structures. 

I was really hoping I'd be able to copy valid ranges of bytes in and out of some user data types I'm using.  It would greatly help manage the legacy mixed-type V-table data blocks that I setup in DL many years ago, reducing a whole bunch of messy address translation issues.

I noticed a thread from 2017 where this MEMCOPY limit was confirmed, there was some mention that this might be addressed at some point.  Is there now a way to do this that I'm missing, or is it still in the plans to add to DMD at some point?  Thanks.

We haven't done anything yet, but we understand the need. We'll look into it.
Title: Re: MEMCOPY and Partial Structures
Post by: franji1 on February 04, 2020, 11:17:27 AM
One workaround is to utilize BYTE/WORD/DWORD union structure members that lay on top of the BIT/BYTE/WORD ACTUAL members that you need to "crack" into/out of.

Then just use a COPY instruction to copy your MHR/DLV type memory on top of/from those "union" structure members that occupy the same memory as the actual members.

Let us know if you need any help with this.
Title: Re: MEMCOPY and Partial Structures
Post by: johnr on February 04, 2020, 01:41:12 PM
Franji,

I saw reference in the older thread to union structure members but I couldn't quite follow - can you point me to a reference?

At the moment I've broken things up into a handful user data types, and with that and some pre-aggregating of the scattered elements into nice contiguous integer data blocks I'm able to MEMCOPY in and out of the working user structures used by the subroutines.  A little additional code and time penalty but it doesn't look too bad.
Title: Re: MEMCOPY and Partial Structures
Post by: franji1 on February 04, 2020, 03:03:28 PM
At the moment I've broken things up into a handful user data types, and with that and some pre-aggregating of the scattered elements into nice contiguous integer data blocks I'm able to MEMCOPY in and out of the working user structures used by the subroutines.  A little additional code and time penalty but it doesn't look too bad.

That works - no need to get into union stuff - it's an advanced C programming concept where different structure members overlay on top of each other.

One example that exists in Designer already is the PeerLink heap structure, PL (not the block).  There are bits for all 16 of the blocks for their Active state, e.g. PL.B0Act, PL.B1Act, PL.B2Act, ? PL.B15.Act.  But then there is also member called PL.Active that is a WORD (16 bits) that represents those 16 bits in a single WORD.  It occupies the SAME MEMORY locations as the bits.  Hence. the LSBit of PL.Active is the same as PL.B0Act bit, and the MSBit of PL.Active is the same as PL.B15Act.

The PL.Error, PL.Updated, and PL.Inhibit are similar WORD struct members that sit on top of the 16 individual blocks' bit members.  Almost everything there is read-only, but the PL.Inhibit and the corresponding individual PL.BxInh bits are read/write.  Hence, you could easily WRITE to the 16 inhibit bits from an MHR or DLV via the MOVE instruction:
MOVE DLV2000 PL.Inhibit
Title: Re: MEMCOPY and Partial Structures
Post by: johnr on February 04, 2020, 04:37:38 PM
I can see where that technique might be helpful in a couple spots ahead.  So far, all of my bit-addressible words were pre-cast into integer table blocks before copying them into the user structs.

MEMCOPY seems to be faster than MOVE or COPY when copying a block of values from what I can tell.

Thanks for the help!
Title: Re: MEMCOPY and Partial Structures
Post by: franji1 on February 04, 2020, 04:53:30 PM
MEMCOPY seems to be faster than MOVE or COPY when copying a block of values from what I can tell.
It is.  MOVE/COPY deals with values, along with any possible conversions.  MEMCOPY just deals with raw memory - hence it is faster.  But unless you are moving a lot of memory (e.g. 50 or more), it is negligible to the PLC scan time.

It's best not to be too concerned with minimizing scan times early on, especially if you are coming from DL (you'll be faster).  There may be other areas you can optimize first, e.g. string functions that can be much more time consuming than a MOVE (Pareto Principle - you'll spend 80% of your scan time in 20% of your code - and it's commonly NOT where you think).  So in a huge program that is running 20ms, you might refactor some "obviously slow" code that gets you down to 19ms (not).  But there could be just a few tweaks where you get the PLC scan time from 20ms down to 2ms (e.g. copying a range of bit memory is S-L-O-W, just tweaked the code to use BYTE/WORD/DWORD casts and the code flew).
Title: Re: MEMCOPY and Partial Structures
Post by: franji1 on February 04, 2020, 04:57:14 PM
FYI, the MATH function TICKus() (tick count in MICRO seconds) helps with profiling code

MATH D42 "TICKus()"  // take a snapshot of the microsecond counter and stick it in D42
STRPRINT // some complicated string script
MATH D42 "TICKus() - D42"  // subtract snapshot from the current counter and stick it back in to D42; D42 will contain the change in the microsecond counter of the STRPRINT
Title: Re: MEMCOPY and Partial Structures
Post by: johnr on February 04, 2020, 05:15:27 PM
Ah, timeGetTime(), now new and improved for the PLC!  (Old die-hard VB6'er here.)

That will definitely find plenty of use during debug, I am moving large enough blocks for it to matter.  Thanks again!