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

Try both in a continuous task. Measured time spent by the code in the periodic task is probably being counted while that task is waiting for each slice of execution time.
 
Try both in a continuous task. Measured time spent by the code in the periodic task is probably being counted while that task is waiting for each slice of execution time.

Are you thinking that 12ms for 125k iterations is not what should be expected? Sounds in the realm of possibility. I haven't done the test on those controllers.
 
You guys need to think about what the compiler and CPU are doing. I thought dmroeder's initial conclusion was obvious. Think about what the computer is doing to compute the address using an array of UDTs. First the computer will multiply the index by the size of the UDT. Then it will add the offset of the item/field of the UDT. Then it will add the base address of the array itself. If the compiler is efficient, it will at compile time add the offset of the field of the variable in the UDT and the base of the compiler so only one addition needs to be done. There are no other ways to make this more efficient.

It is too bad we can't see the code that is generated. Most compilers have an option to generate either the raw assembly language or the list file showing the assembly language compiled so one can see the binary code generated too.
 
You guys need to think about what the compiler and CPU are doing. I thought dmroeder's initial conclusion was obvious. Think about what the computer is doing to compute the address using an array of UDTs. First the computer will multiply the index by the size of the UDT. Then it will add the offset of the item/field of the UDT. Then it will add the base address of the array itself. If the compiler is efficient, it will at compile time add the offset of the field of the variable in the UDT and the base of the compiler so only one addition needs to be done. There are no other ways to make this more efficient.

It is too bad we can't see the code that is generated. Most compilers have an option to generate either the raw assembly language or the list file showing the assembly language compiled so one can see the binary code generated too.

So the older 5370/5570 platform seem to handle 2 DIM arrays and UDT's differently, 2 DIM arrays seem to be much less efficient. 5380/5580 platform seem to have optimized 2 DIM arrays, as the perform similar to UDT's.
 
There may be something going on in this thread that may not be obvious to everyone. Rockwell's current generation of processors do things different than the older generation. Current generation is 5380/5580 (5069/L8). They are significantly faster in most cases and have optimized some things over the previous generation. They have also added new types and math with 64 bit types.

The older platform apparently handled multi dimensional arrays inefficiently. The newer platform seems to have done some optimizing. My tests were with the older platform, the OP's tests are with the newer platform, which are expected to handle most tasks an order of magnitude faster.
 
What is obvious to me is that using an array of UDTs should be much faster than any other method. I know that I am assuming that the compiler writers are trying make efficient code. My ST compiler is not smart enough to combine the array offset with the field offset but in any case it is faster than using a two dimensional array.
 
You guys need to think about what the compiler and CPU are doing.


I have. For

the_udt[X].member_array[Y]


the compiler has to do

&the_udt[0].member_array[0] + (X * sizeof(type(the_udt[0]))) + (Y * sizeof(type(the_udt[0].member_array[0])))


so two adds and two multiplies, where the blue items are known at compile time, and the magenta item probably is as well.

for

the_array[X,Y]


the compiler has to do

&the_array[0,0] + (X * (sizeof(type(the_array[0,0]) * dimension_1)) ) + (Y * sizeof(type(the_array[0,0])))


(assuming row-major ordering). So again two adds and two multiplies.

there may of course be some optimizations available that I am not seeing.

the sizeof(type(the_array[0,0])) could be taken out by associative property of multiplication, but that would actually add a multiplication.

the * sizeof(type(the_array[0,0])) could be removed if it's implicit an available mode of addressing.

But yes, I am not a compiler writer.
 
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
198
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