News:

  • June 29, 2026, 12:58:28 PM

Login with username, password and session length

Author Topic: What is the fastest way to move indexed Unsigned Words?  (Read 27337 times)

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
What is the fastest way to move indexed Unsigned Words?
« on: December 26, 2014, 10:04:52 AM »
I have a data intensive app that is overtaxing my poor PLC. I am moving data around inside of some nested FOR loops, and am looking to save some processing time. What is the fastest way to move a single unsigned word of data to another unsigned word (both of them at variable indexes)? MOVE, MATH, MEMCOPY?
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #1 on: December 26, 2014, 10:37:06 AM »
1. Don't move data.  Use a ring buffer with pointers/indexes to head and tail.  This is true regardless of language (C, Java, Do-more, IEC-61131-3, ...).

I know that not ALL blocks of data are FIFO or LIFO, just random blocks of data.  But start with those that are.  Especially "large" types like STRINGs or other structures, then BITs if you are moving at the bit-level and not optimizing your bit table moves on byte boundaries via casting.  Oh, and tables/blocks that are LONG.

2. Use "memory" type copies where you can, not "value" type copies.  MEMCOPY is faster than MOVER and the other "Assignment" type instructions.  MEMCOPY just moves bytes around from source to destination.  All of the other do "type" intelligent assignment, so you can move VALUEs from an unsigned 16 bit integer into a 32 bit signed (e.g. values from V0..V9 into D0..D9).  Note that the MEMCOPY would NOT work with the V0..V9 to D0..D9 example, but that was just an illustration of the BEHAVIOR of the MOVER-type assignment instruction.  MOVER loads the value and the source-type, then writes out that "value" and the destination-type, properly handling any size/type conversion.  This is done regardless of whether the source and destination are of the same type/size, hence it is slower than straight memory byte access (think C's memcpy) of MEMCOPY.

Note: #1 is MUCH FASTER vs. #2, O(1) vs. O(n), if you understand big-O notation.  All I'm doing in #2 is changing the "constant" in front of O(n).
« Last Edit: December 26, 2014, 10:41:45 AM by franji1 »

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6164
  • Yes Pinky, Do-more will control the world!
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #2 on: December 26, 2014, 10:50:09 AM »
For single simple integers, I think MATH will be fastest...although if array references, probably MOVE. I will echo Mark's thoughts though...structure matters most. Ring buffers for FIFOs, keep running stats where possible (maintain stats of collections as you add/remove items in the collection), and when looping remember the role of .Timeslice.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #3 on: December 26, 2014, 10:56:30 AM »
For example, the way to implement #1 on a bubble-sort on STRINGs, keep your STRING indexes static, but block of a set of V range as the "sorted index".  Say you have 1000 strings in MyData, block off V10000-V10999 for the "sorted" indexes.

1. At top of bubble sort, initialize V10000..V10999 to 0..999
2. Inside the Bubble Sort, whenever you had been looking at MyData[V0] (where V0 is the FOR index), you need to look at MyData[V[V0+10000]] (you can't do this directly, but use a temp V index via MATH).
3. When you "swap", do NOT swap MyData, swap the "sorted indexes", i.e. swap V[V0+10000] and V[V0+1+10000].

The result SHOULD be that your strings are exactly in the original un-sorted order, but instead of MyData0 being the SMALLEST string (it will be the same as it was BEFORE the bubble sort), MyData[V10000] is the smallest.  MyData[V10000+1] is the next smallest...  MyData[V10999] is the largest.

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #4 on: December 26, 2014, 11:11:19 AM »
Mark,
I have used the "sorted index" in the past, and it works very well. I will have to see if I can incorporate it in this app...
I am already using all MEMCOPY's, so I will look elsewhere for opportunities to optimize.
The app is 'merging' two databases  700 'rows' long. I only have 250 milliseconds to complete the task, and I'm 'pausing' comms with ~8 TCP devices in order to accomplish it.
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #5 on: December 26, 2014, 09:22:56 PM »
I only have 250 milliseconds to complete the task
What are you doing in this Task?  Is this the one with nested FOR/NEXT loops?  What are you doing in the inner-most part of the loops?  Can you post your code here?

As BobO mentioned, tweaking .TimeSlice could help.  What do you have it set to now?  What values have you tried?  Larger .TimeSlices will minimize overall Task Execution "completion" time, but also maximize scan time, so there is usually a sweet spot.  .TimeSlice of 65,535 would NEVER yield (best case execution "calendar" time, worst case scan time).  .TimeSlice of 0 would ALWAYS yield (minimal hit to scan time, but HUGE hit to execution "calendar" time).  Try 1000, 5000, 10000, and 20000, and see what "calendar" times and "max scan times" you get with each.  You should see a nice trade-off between the two at a critical point (i.e. bumping the .TimeSlice does NOT improve "calendar" time by much, but takes a HUGE hit on max scan time).  Use MATH with Tickus() at the top and bottom of Tasks to measure how long they take (to MICROsecond resolution!) to measure "calendar" time.

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #6 on: December 27, 2014, 09:49:08 PM »
I have set the TimeSlice to 2000, which seems to be about right for getting the most done without prolonging my scan time any longer than I have to.

I already know of a couple of optimizations to add on Monday, after that I can try to post some code.
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #7 on: December 29, 2014, 08:11:53 AM »
I have set the TimeSlice to 2000 (microseconds), which seems to be about right for getting the most done without prolonging my scan time any longer than I have to.
That value is consistent with what I've seen in practice.  Hopefully we can figure something out.

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #8 on: December 29, 2014, 08:52:54 AM »
I have attached the code from my task as a .txt file.
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #9 on: December 29, 2014, 09:13:38 AM »
What are typical values for your microsecond profiling stats D31 (looping time), and D33 (post processing time).  I bet D33 is the bottle neck (moving 700 STRINGs a couple times).

EDIT: However, your STRINGs are on the short side (8 characters), so that ends up being 12 BYTEs per STRING (4 BYTEs of overhead per STRING).  So each MEMCOPY is moving 8,400 BYTEs, or 16,800 BYTEs every time the TASK is "ran".
« Last Edit: December 29, 2014, 09:19:30 AM by franji1 »

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #10 on: December 29, 2014, 09:39:50 AM »
Mark,
D33 is consistent at ~5500
D31 is all over from >800,000 to ~20,000 depending on how much data is moving through.
I really don't like all the 'temp' memory that I am using in this app, but I could not see a better way of preserving the 'live' data that is being manipulated in other parts of the app while this task is running. I really need the final MEMCOPY's to all happen in one scan.
If you can see a better way then let me know.
Thanks!

FYI, My Max scan time is 28.1ms. and the average runs about 750 microseconds.
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #11 on: December 29, 2014, 10:16:54 AM »
So it's NOT the STRING stuff at the end.  Hmmmm....

Your inner loop logic is running a possible 490,000 times (700 x 700).

You might move the RST C15 from the inner loop to between the two FOR instructions (you would NOT need the $On contact because power flow after a FOR is always ON).  It appears that it is only SET when you BREAK out of the inner FOR/NEXT loop.

Organize the 3 D20 relational contacts rungs in the inner-loop that are "mutually exclusive" in the order of MOST Likely to occur to LEAST Likely to occur (I'm guessing that the D20 == 0 contact is "least" likely, so put that 3rd - not sure which of the other two is more likely).  You can then actually change the 3rd rung input logic to be just a $On NO Contact instead of the D20 == 0 relational contact because if you did not continue/break from the previous two D20 relational contact rungs, then it is true that D20 will equal 0 if you get to THAT 3rd rung).

If these two modifications reduce the execution time in that inner loop by just 10% - 20%, it will help.

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3830
    • Host Engineering
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #12 on: December 29, 2014, 10:23:03 AM »
You might also replace your
  MATH V17 "V26"
in the inner-loop with a simple
  MOVE V26 V17

MATH has some overhead that MOVE does not.  They both basically do a Load Value/Out Value.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6164
  • Yes Pinky, Do-more will control the world!
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #13 on: December 29, 2014, 10:49:40 AM »
You might also replace your
  MATH V17 "V26"
in the inner-loop with a simple
  MOVE V26 V17

MATH has some overhead that MOVE does not.  They both basically do a Load Value/Out Value.

MATH will be faster for integers, I think, since it is all copro based. MOVE isn't.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

plcnut

  • Hero Member
  • *****
  • Posts: 814
    • premiersi.com
Re: What is the fastest way to move indexed Unsigned Words?
« Reply #14 on: December 29, 2014, 03:16:33 PM »
The application is currently running within spec. The changes made today have really helped. I will continue to monitor how it does for a few days.
Thanks for the suggestions; it really helps me to know how to streamline :)
Circumstances don't determine who we are, they only reveal it.

~Jason Wolthuis
Premier Systems Integration, LLC
http://premiersi.com