ControlLogix: Performance of 2-dimensional array vs array of array UDT

MoraleC2

Member
Join Date
Jan 2016
Location
East Coast
Posts
23
I have a task that could easily be solved using a 2-dimensional array using a ControlLogix processor, V32+. Basically it will loop through two different arrays and build a list of indices associated with another list of indices. So it's a simple matter of:

for x:=0 To MaxX Do 
for y:=0 To MaxY Do
<code>;
End_For;
End_For;


I know 2-dimensional arrays take a toll on performance, but I don't know how they would compare to, say, an array of UDT instances that have an array in each. My question is: which would be more efficient from an execution time perspective: processing a 2-dimensional array - e.g., indices[x,y] - or an array of UDT instances that are arrays - e.g., incides1[x].indices2[y]?

Thank you for your time.
 
Last edited:
I'd imagine that anyone needing to this whilst controlling a process will have placed this logic in a low priority task (whilst moving the rest of the logic to higher priority ones), or removed the outer for loop and kept a counter on the task loop instead (thus spreading the load on the processor).

I've done that on stuff like monitoring a given Profibus network for example so that the program wouldn't stop checking all the nodes with system calls.
 
Inquiring minds want to know...

So I made a 2D array [2,500] and a UDT like you mentioned Tag[2].Tag[500] (DINT data types). Wrote the same loop in a continuous task, the only logic was 2 simple loops, exactly like you described. PLC = 1769-L30ER v30

  • No logic scanning: 0.03ms AVE, 1.35ms MAX
  • 2D Array scanning: 5.5ms AVE, 7.2ms MAX
  • UDT scanning: 1.8ms AVE, 3.1ms MAX

So making a UDT seems more efficient than using 2D arrays.
 
Inquiring minds want to know...

So I made a 2D array [2,500] and a UDT like you mentioned Tag[2].Tag[500] (DINT data types). Wrote the same loop in a continuous task, the only logic was 2 simple loops, exactly like you described. PLC = 1769-L30ER v30

  • No logic scanning: 0.03ms AVE, 1.35ms MAX
  • 2D Array scanning: 5.5ms AVE, 7.2ms MAX
  • UDT scanning: 1.8ms AVE, 3.1ms MAX

So making a UDT seems more efficient than using 2D arrays.


for grins and giggles, could you try swapping the order of the indices i.e. increment the Y index in the outer loop and the X index in the inner loop, and see if there is any change, please?
 
for grins and giggles, could you try swapping the order of the indices i.e. increment the Y index in the outer loop and the X index in the inner loop, and see if there is any change, please?

Good idea, I'll do a new post in a minute because I think there is a bit of a difference.
 
Good idea, I'll do a new post in a minute because I think there is a bit of a difference.


Any difference may also depend on the dimensions of the array.

I once helped someone with a slow program. The were cycling over a 2D array the "wrong" way and generating six million page faults a second (VAX/VMS, several decades ago). Reversing the order dropped that to essentially zero and sped the process up by a few orders of magnitude.

I wouldn't think page faults specifically would be an issue in summat as simple as a ControlLogix, but you never know, there might be some other form of CPU caching behavior in play.
 
So for clarity, I have 2 loops now, outer loop is the smaller index and where the outer loop is the larger index (I think that is what you wanted):

  • 2DIM short loop first: 7.0ms MAX, 5.5ms MIN
  • 2DIM large loop first: 8.0ms MAX, 6.1ms MIN
  • UDT short loop first: 3.1ms MAX 1.8ms MIN
  • UDT large loop first: 3.7ms MAX 2.3ms MIN

Code:
For i:= 0 to 1 Do
	for j:= 0 to 499 Do
		If less_slow[i].Val1[j] = 1 Then
			// Stuff

vs

For j:= 0 to 499 Do
	for i:= 0 to 1 Do
		If less_slow[i].Val1[j] = 1 Then
			// Stuff
 
So for clarity, I have 2 loops now. . .

Thank you for the data. I finally managed to get access to a test processor (1756-L84E) and ran code almost exactly as follows:

Code:
	For i := 0 To 249 Do
		For j := 0 To 499 Do
			If test2DArr[i,j] <> -1 then
				// Do things
			End_If;
		End_For;
	End_For;

Versus
Code:
	For i := 0 To 249 Do
		For j := 0 To 499 Do
			If testUDTArr[i].testNestedUDTArr[j] <> -1 then
				// Do things
			End_If;
		End_For;
	End_For;

My results were as follows:

First (2D array):
- Max: 12.33ms
- Min: 12.13ms

Second (nested UDT arrays):
- Max: 12.78ms
- Min: 12.63ms

So, in my experiment, the nested UDT arrays were less efficient, by about 4%. But this was in a periodic task, not continuous like yours. I don't know if that makes any difference, but either way it's interesting that we got different results. I wonder if it's a matter of the type of processor used?
 
Last edited:
But this was in a periodic task, not continuous like yours. I don't know if that makes any difference, but either way it's interesting that we got different results. I wonder if it's a matter of the type of processor used?

Do you have more periodic tasks? I'm very surprised by this considering the supposed difference in processing power between the L84 and L30.
 
It's quite possible that 2D arrays are handled different in the newer platform controllers. It at least seems that way based on your result.
 
I'm very surprised by this considering the supposed difference in processing power between the L84 and L30.

The OP's result is probably much faster than it would run on my 1769-L30ER. My loops were 2x500, his is 250x500

EDIT: 2D array, 100x500 loop, 297ms max, 294ms min on my L30ER
EDIT2: UDT, 100x500 loop, 93ms max, 90ms min

So it looks like something is different about how the newer controllers handle 2D arrays compared to the older generation controllers
 
Last edited:

Similar Topics

Why does the controllogix redundancy modules use a single mode fiber vs multimode fiber?
Replies
1
Views
86
Hello, I have two 16 point input cards and 1 16 point output card showing module faulted on my IO tree in Logix Designer. The fault code is...
Replies
7
Views
216
Hello, My associate and I are trying to sync up two ControlLogix racks (7-slot chassis) with identical modules. We are able to see the secondary...
Replies
4
Views
197
Trying to setup a message read via Ethernet. I have the path setup as 1, 1, 2, 192.168.66.10 I get an error code 1, ext err 315. I am beating...
Replies
9
Views
233
I have a redundant ControlLogix being set up. This program reads a value from a remote site which happens to be SLC PLC. Rockwell mentions SLC...
Replies
2
Views
96
Back
Top Bottom