Optimize your code. (Tips and techniques)
Spire_Jeff
Formerly Caffeinated Programmer
This thread is dedicated to known ways to speed up your code execution, reduce memory usage, or make code easier to reuse. This thread should not be used to debate techniques (create a separate thread to handle this). If possible, post proof of speed increase or reduced memory usage.
############################
# Reduce Memory Consumption #
############################
Tip - When using multiple ports on a virtual device, use sequential ports starting at port 1.
Proof - Tech support says so
The processor allocates memory sequentially for ports. Even if you only use port 1 and port 100, the processor allocates memory to track all ports between 1 and 100 in addition to ports 1 and 100.
##########################
# Faster Loop Execution #
##########################
Tip - When using a For loop, reduce the work being done in the evaluation portion of the for loop. The most efficient for loop I have found counts down, not up.
Example - for(x=MaxNum;x;x--)
Proof -
##########################
# Faster Loop Execution #
##########################
Tip - Use stack_vars as counters in for loops.
Proof -
These are the few that come to mind right now. I look forward to hearing about other optimizations out there.
Jeff
############################
# Reduce Memory Consumption #
############################
Tip - When using multiple ports on a virtual device, use sequential ports starting at port 1.
Proof - Tech support says so
##########################
# Faster Loop Execution #
##########################
Tip - When using a For loop, reduce the work being done in the evaluation portion of the for loop. The most efficient for loop I have found counts down, not up.
Example - for(x=MaxNum;x;x--)
Proof -
Line 13 (16:16:47):: START...FOR (nLoop = 1; nLoop <= LENGTH_ARRAY(nInfo); nLoop++) Line 14 (16:16:51):: ...END Line 15 (16:16:51):: pass 1: 3876ms Line 16 (16:17:07):: START...FOR (nLoop = 1; nLoop <= MAX_LENGTH_ARRAY(nInfo); nLoop++) Line 17 (16:17:11):: ...END Line 18 (16:17:11):: pass 2: 3694ms Line 19 (16:17:27):: START...FOR (nLoop = 1, nMax = MAX_LENGTH_ARRAY(nInfo); nLoop <= nMax; nLoop++) Line 20 (16:17:30):: ...END Line 21 (16:17:30):: pass 3: 2019ms Line 22 (16:17:48):: START...FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop > 0; nLoop--) Line 23 (16:17:50):: ...END Line 24 (16:17:50):: pass 4: 1855ms Line 25 (16:18:08):: START...FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop; nLoop--) Line 26 (16:18:10):: ...END Line 27 (16:18:10):: pass 5: 1557ms
##########################
# Faster Loop Execution #
##########################
Tip - Use stack_vars as counters in for loops.
Proof -
Line 13 (16:16:47):: START...FOR (nLoop = 1; nLoop <= LENGTH_ARRAY(nInfo); nLoop++) Line 14 (16:16:51):: ...END Line 15 (16:16:51):: pass 1: 3876ms This is the same format as pass 1, but with a stack_var. Line 23 (16:28:35):: START...FOR (snLoop = 1; snLoop <= LENGTH_ARRAY(nInfo); snLoop++) Line 24 (16:28:39):: ...END Line 25 (16:28:39):: pass 0: 3478ms$0D$0A Line 25 (16:18:08):: START...FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop; nLoop--) Line 26 (16:18:10):: ...END Line 27 (16:18:10):: pass 5: 1557ms This is the same format as pass 5, but with a stack_var used for the counter Line 28 (16:18:28):: START...FOR (snLoop = MAX_LENGTH_ARRAY(nInfo); snLoop; snLoop--) Line 29 (16:18:29):: ...END Line 30 (16:18:29):: pass 6: 1213ms
These are the few that come to mind right now. I look forward to hearing about other optimizations out there.
Jeff
Comments
-
Jeff,
This is a very interesting topic. I have been doing this for about ten years now and I never even thought about the difference between using an increasing or decreasing value "for loop". It makes total sense though.
Out of curiosity how do you calculate the speed of the program? I have some ideas on how to do it but I have never attempted it so I thought why re-invent the wheel. I'll just ask you. -
Good topic Jeff, I've been working on updating my code now for a few months and wow, I can't believe some of the code I wrote 10, even 5 years ago even worked.
-
This topic is the child of me reworking some code and speed/memory use is now my focus. (code works, but takes 25 minutes on reboot
) I figured that since I am massaging the code, I might as well make some simple changes that won't change the functionality, only the speed in which it happens. I am also consolidating ports and renumbering devices to fit a standard I have created.
As for the timing, I have two methods I have used. The method listed above is done by parsing strings and calculating time based on when the string arrives. This was written by someone else (unknown to me), but it was what I had around. I have also done testing using a timeline. I start the timeline just before executing the code, then pause it right after the code finishes. I then use the timeline time to decide how long things took. I'm am not sure which is more accurate, but I believe that in either case, you are only talking a couple of ms room for error. I would love to know for sure, but I figure as long as I use the same method for all variations being tested, the overhead involved should be irrelevant in the final comparison.
One thing becomes clear tho, the processor is very fast. I like to make things happen a LOT (loops over 50000 times) so that most of the tests take at least 1 second (give or take a little). This helps to magnify the actual difference. Right now, the test is the only code running on the processor, but in the future I might start injecting the test code into a work code chunk to see if there is a difference in speed.
Jeff -
Doesn't that apply to non virtual devices also?Spire_Jeff wrote:Tip - When using multiple ports on a virtual device, use sequential ports starting at port 1. -
Doesn't that apply to non virtual devices also?
Well, I don't think you have a choice on non-virtual devices. If you need to use port 17 on an NI-3100, you have to use it. I am not aware of any way to remap the physical device.
I also updated the for loop tests and added benchmark test code to a separate thread in Tips and Tricks.
#########################
# Squeeze EVERY last bit out of the processor
#########################
tip - If you need to make every single processor cycle count, use ON[variable] and OFF[variable] instead of variable=TRUE and variable=FALSE.
Proof - see the other post as the information is there. Over 70,000 cycles, ON and OFF were 95ms faster.
P.S.
Anyone know of any other competing code bits that would be fun to test? -
How about adding to the on off test, setting the variable to 1 and 0 instead of true and false?
-
How about adding to the on off test, setting the variable to 1 and 0 instead of true and false?
Believe it or not, 1 and 0 are slower than TRUE and FALSE!Line 122 (19:05:53):: ********************************************************* Line 123 (19:05:53):: * TEST 8 REPORT: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 124 (19:05:53):: * Most recent 5 runs: Line 125 (19:05:53):: * 1: 1903ms Line 126 (19:05:53):: * 2: 1903ms Line 127 (19:05:53):: * 3: 1904ms Line 128 (19:05:53):: * 4: 1904ms Line 129 (19:05:53):: * 5: 1902ms Line 130 (19:05:53):: *---------------------------------------------------------- Line 131 (19:05:53):: * Average run time: 1902ms - over 5 tests Line 132 (19:05:53):: ********************************************************* Line 133 (19:05:53):: ********************************************************* Line 134 (19:05:53):: * TEST 9 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 135 (19:05:53):: * Most recent 5 runs: Line 136 (19:05:53):: * 1: 1999ms Line 137 (19:05:53):: * 2: 1998ms Line 138 (19:05:53):: * 3: 1997ms Line 139 (19:05:53):: * 4: 1996ms Line 140 (19:05:53):: * 5: 1998ms Line 141 (19:05:53):: *---------------------------------------------------------- Line 142 (19:05:53):: * Average run time: 1996ms - over 5 tests Line 143 (19:05:53):: ********************************************************* Line 144 (19:05:53):: ********************************************************* Line 145 (19:05:53):: * TEST 10 REPORT: nInfo[nLoop]=1 .. nInfo[nLoop]=0 Line 146 (19:05:53):: * Most recent 5 runs: Line 147 (19:05:53):: * 1: 2024ms Line 148 (19:05:53):: * 2: 2024ms Line 149 (19:05:53):: * 3: 2024ms Line 150 (19:05:53):: * 4: 2025ms Line 151 (19:05:53):: * 5: 2024ms Line 152 (19:05:53):: *---------------------------------------------------------- Line 153 (19:05:53):: * Average run time: 2024ms - over 5 tests Line 154 (19:05:53):: *********************************************************
Jeff -
Up, down, or sideways
I did some testing myself and didn?t find that to be the case at all. The time it takes to count up or down in a FOR loop is nearly absolutely identical at least using the method I tried.Spire_Jeff wrote:The most efficient for loop I have found counts down, not up.
I was looking at your benchmark code in the other thread and I think the testing method may be introducing too much error into the equation and giving you inaccurate conclusions. Why do all the pausing, killing, and creating of TIMELINEs when a simple GET_TIMER should suffice?
Here is my FOR loop counting code with results. It?s just a FOR loop that counts to 1 million and that?s it aside from the GET_TIMER and SEND_STRING 0 statements. I tested both up and down 10 times and each loop takes about 13 seconds to complete so it should be a plenty big enough sampling size.DEFINE_DEVICE dvTP = 10001:1:0 DEFINE_EVENT BUTTON_EVENT[dvTP,1] { PUSH: { LONG x LONG start LONG finish start = GET_TIMER SEND_STRING 0,"'Counting up - timer start = ',ITOA(start)" FOR (x=1; x<=1000000; x++) { } finish = GET_TIMER SEND_STRING 0,"'Counting up - timer end = ',ITOA(finish)" SEND_STRING 0,"'Counting up - total time = ',ITOA(finish-start)" } } BUTTON_EVENT[dvTP,2] { PUSH: { LONG x LONG start LONG finish start = GET_TIMER SEND_STRING 0,"'Counting down - timer start = ',ITOA(start)" FOR (x=1000000; x>0; x--) { } finish = GET_TIMER SEND_STRING 0,"'Counting down - timer forward end = ',ITOA(finish)" SEND_STRING 0,"'Counting down - total time = ',ITOA(finish-start)" } }
Here are the results for counting up.Line 1 :: Counting up - timer start = 3714 - 17:30:45 Line 2 :: Counting up - timer end = 3846 - 17:30:58 Line 3 :: [b]Counting up - total time = 132[/b] - 17:30:58 Line 4 :: Counting up - timer start = 3866 - 17:31:00 Line 5 :: Counting up - timer end = 3997 - 17:31:13 Line 6 :: [b]Counting up - total time = 131[/b] - 17:31:13 Line 7 :: Counting up - timer start = 4010 - 17:31:14 Line 8 :: Counting up - timer end = 4142 - 17:31:28 Line 9 :: [b]Counting up - total time = 132[/b] - 17:31:28 Line 10 :: Counting up - timer start = 4159 - 17:31:29 Line 11 :: Counting up - timer end = 4291 - 17:31:42 Line 12 :: [b]Counting up - total time = 132[/b] - 17:31:42 Line 13 :: Counting up - timer start = 4309 - 17:31:44 Line 14 :: Counting up - timer end = 4441 - 17:31:57 Line 15 :: [b]Counting up - total time = 132[/b] - 17:31:57 Line 16 :: Counting up - timer start = 4459 - 17:31:59 Line 17 :: Counting up - timer end = 4591 - 17:32:13 Line 18 :: [b]Counting up - total time = 132[/b] - 17:32:13 Line 19 :: Counting up - timer start = 4710 - 17:32:24 Line 20 :: Counting up - timer end = 4842 - 17:32:38 Line 21 :: [b]Counting up - total time = 132[/b] - 17:32:38 Line 22 :: Counting up - timer start = 4873 - 17:32:41 Line 23 :: Counting up - timer end = 5004 - 17:32:54 Line 24 :: [b]Counting up - total time = 131[/b] - 17:32:54 Line 25 :: Counting up - timer start = 5047 - 17:32:58 Line 26 :: Counting up - timer end = 5179 - 17:33:11 Line 27 :: [b]Counting up - total time = 132[/b] - 17:33:11 Line 28 :: Counting up - timer start = 5198 - 17:33:13 Line 29 :: Counting up - timer end = 5330 - 17:33:27 Line 30 :: [b]Counting up - total time = 132[/b] - 17:33:27
And here are for all practical purposes identical results for counting down.Line 31 :: Counting down - timer start = 5368 - 17:33:30 Line 32 :: Counting down - timer forward end = 5499 - 17:33:44 Line 33 :: [b]Counting down - total time = 131[/b] - 17:33:44 Line 34 :: Counting down - timer start = 5517 - 17:33:45 Line 35 :: Counting down - timer forward end = 5648 - 17:33:59 Line 36 :: [b]Counting down - total time = 131[/b] - 17:33:59 Line 37 :: Counting down - timer start = 5671 - 17:34:01 Line 38 :: Counting down - timer forward end = 5803 - 17:34:14 Line 39 :: [b]Counting down - total time = 132[/b] - 17:34:14 Line 40 :: Counting down - timer start = 5826 - 17:34:16 Line 41 :: Counting down - timer forward end = 5958 - 17:34:29 Line 42 :: [b]Counting down - total time = 132[/b] - 17:34:29 Line 43 :: Counting down - timer start = 6014 - 17:34:35 Line 44 :: Counting down - timer forward end = 6146 - 17:34:48 Line 45 :: [b]Counting down - total time = 132[/b] - 17:34:48 Line 46 :: Counting down - timer start = 6163 - 17:34:50 Line 47 :: Counting down - timer forward end = 6294 - 17:35:03 Line 48 :: [b]Counting down - total time = 131[/b] - 17:35:03 Line 49 :: Counting down - timer start = 6306 - 17:35:04 Line 50 :: Counting down - timer forward end = 6438 - 17:35:18 Line 51 :: [b]Counting down - total time = 132[/b] - 17:35:18 Line 52 :: Counting down - timer start = 6507 - 17:35:25 Line 53 :: Counting down - timer forward end = 6639 - 17:35:38 Line 54 :: [b]Counting down - total time = 132[/b] - 17:35:38 Line 55 :: Counting down - timer start = 6651 - 17:35:39 Line 56 :: Counting down - timer forward end = 6782 - 17:35:52 Line 57 :: [b]Counting down - total time = 131[/b] - 17:35:52 Line 58 :: Counting down - timer start = 6794 - 17:35:53 Line 59 :: Counting down - timer forward end = 6926 - 17:36:06 Line 60 :: [b]Counting down - total time = 132[/b] - 17:36:06
-
Actually I was thinking more in the lines of real TP device ports vs virtual TP ports. It might just be the way I personally think but when I think of a virtual device port and their resources and how I use them I think of them more as a virtual TP port not so much as a virtual NI device port. It might just be that the way I think is slightly abnormal.Spire_Jeff wrote:Well, I don't think you have a choice on non-virtual devices. If you need to use port 17 on an NI-3100, you have to use it. I am not aware of any way to remap the physical device.
However if your physical NI port aren't defined the same should hold true, they won't take up resources so use those ports sequentially as well and not use serial ports 1 & 7 leaving 2-6 un-used for example. -
Joe Hebert wrote: »I did some testing myself and didn?t find that to be the case at all. The time it takes to count up or down in a FOR loop is nearly absolutely identical at least using the method I tried.
Look closer at the for loops
The way to make counting down faster is to reduce the operations. Try the following:for(x=Max;x;x--){}
Notice how the comparison is just x, not x>0. That is where I think the gain comes from.Joe Hebert wrote: »I was looking at your benchmark code in the other thread and I think the testing method may be introducing too much error into the equation and giving you inaccurate conclusions. Why do all the pausing, killing, and creating of TIMELINEs when a simple GET_TIMER should suffice?
I could probably change the timeline aspect, but that was my original thought on the task. I may have been trying something else at the time, but that's the way it was so I just kept it. It shouldn't make a difference as long as the overhead is the same from test to test, but if I get a moment, I might try modifying the code to use your suggestion.
Jeff -
Actually I was thinking more in the lines of real TP device ports vs virtual TP ports. It might just be the way I personally think but when I think of a virtual device port and their resources and how I use them I think of them more as a virtual TP port not so much as a virtual NI device port. It might just be that the way I think is slightly abnormal.
However if your physical NI port aren't defined the same should hold true, they won't take up resources so use those ports sequentially as well and not use serial ports 1 & 7 leaving 2-6 un-used for example.
I see where you are coming from now. Yes, the same holds true for touch panels. While we are mentioning touch panels and ports, I just recalled another thing... I believe that the set_virtual_channel_count() command is done in blocks of 255 or was it 256. I will have to try to find the original post or the documentation to verify this. I guess the general rule of thumb is to start at the lowest number (generally 1) and try to go up sequentially in everything AMX.
The only exception that I have found is in actual device numbers. If it's not defined, it won't be tracked.
Jeff -
Well if you're not going to compare apples to apples what fun are you?Spire_Jeff wrote: »Look closer at the for loops
The way to make counting down faster is to reduce the operations. Try the following:for(x=Max;x;x--){}
Notice how the comparison is just x, not x>0. That is where I think the gain comes from.
A FOR loop that counts down is still not faster but I do agree that the comparison of x vs. x>0 is faster which is good to know. -
Sorry, I don?t believe it and I sure wouldn?t expect them to be different. I tested 1 and 0 and then TRUE and FALSE one million times in a FOR loop and saw no difference. The results are below.Spire_Jeff wrote:Believe it or not, 1 and 0 are slower than TRUE and FALSE!
I got the opposite results. Running through a FOR loop one million times I found that TRUE/FALSE (1/0) is faster than ON/OFF by about 5%. The results are below.Spire_Jeff wrote:If you need to make every single processor cycle count, use ON[variable] and OFF[variable] instead of variable=TRUE and variable=FALSE.
Here is the code ? The FOR loops each take about 20 seconds to run.DEFINE_DEVICE dvTP = 10001:1:0 DEFINE_VARIABLE INTEGER nVar DEFINE_EVENT BUTTON_EVENT[dvTP,1] { PUSH: { LONG x LONG start LONG finish start = GET_TIMER SEND_STRING 0,"'ON/OFF - timer start = ',ITOA(start)" FOR (x=1; x<=1000000; x++) { ON[nVar] OFF[nVar] } finish = GET_TIMER SEND_STRING 0,"'ON/OFF - timer end = ',ITOA(finish)" SEND_STRING 0,"'ON/OFF - total time = ',ITOA(finish-start)" } } BUTTON_EVENT[dvTP,2] { PUSH: { LONG x LONG start LONG finish start = GET_TIMER SEND_STRING 0,"'1/0 - timer start = ',ITOA(start)" FOR (x=1; x<=1000000; x++) { nVar = 1 nVar = 0 } finish = GET_TIMER SEND_STRING 0,"'1/0 - timer end = ',ITOA(finish)" SEND_STRING 0,"'1/0 - total time = ',ITOA(finish-start)" } } BUTTON_EVENT[dvTP,3] { PUSH: { LONG x LONG start LONG finish start = GET_TIMER SEND_STRING 0,"'TRUE/FALSE - timer start = ',ITOA(start)" FOR (x=1; x<=1000000; x++) { nVar = TRUE nVar = FALSE } finish = GET_TIMER SEND_STRING 0,"'TRUE/FALSE - timer end = ',ITOA(finish)" SEND_STRING 0,"'TRUE/FALSE - total time = ',ITOA(finish-start)" } }
And here are the results which show that ON/OFF is slightly slower than TRUE/FALSE (1/0) and that TRUE/FALSE is the same as 1/0.Line 1 :: ON/OFF - timer start = 6300 - 20:18:16 Line 2 :: ON/OFF - timer end = 6516 - 20:18:38 Line 3 :: [b]ON/OFF - total time = 216[/b] - 20:18:38 Line 4 :: ON/OFF - timer start = 6537 - 20:18:40 Line 5 :: ON/OFF - timer end = 6754 - 20:19:02 Line 6 :: [b]ON/OFF - total time = 217[/b] - 20:19:02 Line 7 :: ON/OFF - timer start = 6776 - 20:19:04 Line 8 :: ON/OFF - timer end = 6992 - 20:19:26 Line 9 :: [b]ON/OFF - total time = 216[/b] - 20:19:26 Line 10 :: ON/OFF - timer start = 7017 - 20:19:28 Line 11 :: ON/OFF - timer end = 7234 - 20:19:50 Line 12 :: [b]ON/OFF - total time = 217[/b] - 20:19:50 Line 13 :: ON/OFF - timer start = 7292 - 20:19:56 Line 14 :: ON/OFF - timer end = 7509 - 20:20:17 Line 15 :: [b]ON/OFF - total time = 217[/b] - 20:20:17 Line 16 :: 1/0 - timer start = 7563 - 20:20:23 Line 17 :: 1/0 - timer end = 7768 - 20:20:43 Line 18 :: [b]1/0 - total time = 205[/b] - 20:20:43 Line 19 :: 1/0 - timer start = 7789 - 20:20:45 Line 20 :: 1/0 - timer end = 7994 - 20:21:06 Line 21 :: [b]1/0 - total time = 205[/b] - 20:21:06 Line 22 :: 1/0 - timer start = 8025 - 20:21:09 Line 23 :: 1/0 - timer end = 8229 - 20:21:30 Line 24 :: [b]1/0 - total time = 204[/b] - 20:21:30 Line 25 :: 1/0 - timer start = 8251 - 20:21:32 Line 26 :: 1/0 - timer end = 8456 - 20:21:52 Line 27 :: [b]1/0 - total time = 205[/b] - 20:21:52 Line 28 :: 1/0 - timer start = 8494 - 20:21:56 Line 29 :: 1/0 - timer end = 8698 - 20:22:17 Line 30 :: [b]1/0 - total time = 204[/b] - 20:22:17 Line 31 :: TRUE/FALSE - timer start = 8717 - 20:22:18 Line 32 :: TRUE/FALSE - timer end = 8921 - 20:22:39 Line 33 :: [b]TRUE/FALSE - total time = 204[/b] - 20:22:39 Line 34 :: TRUE/FALSE - timer start = 8937 - 20:22:40 Line 35 :: TRUE/FALSE - timer end = 9142 - 20:23:01 Line 36 :: [b]TRUE/FALSE - total time = 205[/b] - 20:23:01 Line 37 :: TRUE/FALSE - timer start = 9165 - 20:23:03 Line 38 :: TRUE/FALSE - timer end = 9370 - 20:23:24 Line 39 :: [b]TRUE/FALSE - total time = 205[/b] - 20:23:24 Line 40 :: TRUE/FALSE - timer start = 9429 - 20:23:30 Line 41 :: TRUE/FALSE - timer end = 9633 - 20:23:50 Line 42 :: [b]TRUE/FALSE - total time = 204[/b] - 20:23:50 Line 43 :: TRUE/FALSE - timer start = 9657 - 20:23:53 Line 44 :: TRUE/FALSE - timer end = 9862 - 20:24:13 Line 45 :: [b]TRUE/FALSE - total time = 205[/b] - 20:24:13
-
As Eminem would say: I guess it back to the lab again....
When I get into the office, I will try to mix things up a little and see if I can figure out why the results I am getting are different.
Jeff -
My guess is that not all timelines are created (or killed or paused) equal. Maybe there should be a test for that.:)Spire_Jeff wrote:When I get into the office, I will try to mix things up a little and see if I can figure out why the results I am getting are different.
It?s my opinion that the testing method should be as simple and straight forward as possible so that the testing method itself doesn?t end up skewing the results. -
I really like this post
I think this post is great, although there has been little consensus, makes me want to do some testing as well. -
Jeff,Spire_Jeff wrote: »I will try to mix things up a little and see if I can figure out why the results I am getting are different.
It should be noted that the tests I ran were on an old NI-700 with the latest Duet firmware. -
subscribed, excellent thread!
-
-
Well levels are added in blocks of 8 and it would make sense that channels are added in blocks of 256. Also when defining virtual ports above port 1 you can't always trust the master to add resource for it unless you use set_virtual_port_count since by default virtuals have just one port. I used to think the act of defining a virtual port above 1 would be good enough but now I always set my port counts on virtuals if using more than one port per dev number.Spire_Jeff wrote:I believe that the set_virtual_channel_count() command is done in blocks of 255 or was it 256. -
I?m going to be Internetless this morning so if someone wants to jump in and play the role of jacka.ss please feel free.
-
Sample Code
Folks,
Here are some testing modules used in Tech Support for many years. Guy Minervini shared these with me.
Have Fun!
-Jamie -
Folks,
Here are some testing modules used in Tech Support for many years. Guy Minervini shared these with me.
Have Fun!
-Jamie
it gets even better!
some reputation for you
-
Spire_Jeff wrote: »Believe it or not, 1 and 0 are slower than TRUE and FALSE!
Line 122 (19:05:53):: ********************************************************* Line 123 (19:05:53):: * TEST 8 REPORT: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 124 (19:05:53):: * Most recent 5 runs: Line 125 (19:05:53):: * 1: 1903ms Line 126 (19:05:53):: * 2: 1903ms Line 127 (19:05:53):: * 3: 1904ms Line 128 (19:05:53):: * 4: 1904ms Line 129 (19:05:53):: * 5: 1902ms Line 130 (19:05:53):: *---------------------------------------------------------- Line 131 (19:05:53):: * Average run time: 1902ms - over 5 tests Line 132 (19:05:53):: ********************************************************* Line 133 (19:05:53):: ********************************************************* Line 134 (19:05:53):: * TEST 9 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 135 (19:05:53):: * Most recent 5 runs: Line 136 (19:05:53):: * 1: 1999ms Line 137 (19:05:53):: * 2: 1998ms Line 138 (19:05:53):: * 3: 1997ms Line 139 (19:05:53):: * 4: 1996ms Line 140 (19:05:53):: * 5: 1998ms Line 141 (19:05:53):: *---------------------------------------------------------- Line 142 (19:05:53):: * Average run time: 1996ms - over 5 tests Line 143 (19:05:53):: ********************************************************* Line 144 (19:05:53):: ********************************************************* Line 145 (19:05:53):: * TEST 10 REPORT: nInfo[nLoop]=1 .. nInfo[nLoop]=0 Line 146 (19:05:53):: * Most recent 5 runs: Line 147 (19:05:53):: * 1: 2024ms Line 148 (19:05:53):: * 2: 2024ms Line 149 (19:05:53):: * 3: 2024ms Line 150 (19:05:53):: * 4: 2025ms Line 151 (19:05:53):: * 5: 2024ms Line 152 (19:05:53):: *---------------------------------------------------------- Line 153 (19:05:53):: * Average run time: 2024ms - over 5 tests Line 154 (19:05:53):: *********************************************************
Jeff
I switched the ID around to see if that changed anything. Here are the results:Line 1 (16:07:51):: ********************************************************* Line 2 (16:07:51):: * TEST 8 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 3 (16:07:51):: * Most recent 5 runs: Line 4 (16:07:51):: * 1: 1997ms Line 5 (16:07:51):: * 2: 1997ms Line 6 (16:07:51):: * 3: 1998ms Line 7 (16:07:51):: * 4: 1998ms Line 8 (16:07:51):: * 5: 1998ms Line 9 (16:07:51):: *---------------------------------------------------------- Line 10 (16:07:51):: * Average run time: 1997ms - over 5 tests Line 11 (16:07:51):: ********************************************************* Line 12 (16:07:51):: ********************************************************* Line 13 (16:07:51):: * TEST 9 REPORT: nInfo[nLoop]=1 .. nInfo[nLoop]=0 Line 14 (16:07:51):: * Most recent 5 runs: Line 15 (16:07:51):: * 1: 2025ms Line 16 (16:07:51):: * 2: 2026ms Line 17 (16:07:51):: * 3: 2024ms Line 18 (16:07:51):: * 4: 2024ms Line 19 (16:07:51):: * 5: 2024ms Line 20 (16:07:51):: *---------------------------------------------------------- Line 21 (16:07:51):: * Average run time: 2024ms - over 5 tests Line 22 (16:07:51):: ********************************************************* Line 23 (16:07:51):: ********************************************************* Line 24 (16:07:51):: * TEST 10 REPORT: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 25 (16:07:51):: * Most recent 5 runs: Line 26 (16:07:51):: * 1: 1903ms Line 27 (16:07:51):: * 2: 1903ms Line 28 (16:07:51):: * 3: 1901ms Line 29 (16:07:51):: * 4: 1902ms Line 30 (16:07:51):: * 5: 1904ms Line 31 (16:07:51):: *---------------------------------------------------------- Line 32 (16:07:51):: * Average run time: 1902ms - over 5 tests Line 33 (16:07:51):: *********************************************************
Now, I am not sure what else could be different between the tests, but I am about to try your method. I am running these tests on a newer NI-900 and based on some other benchmarks I have, this NI-900 is running almost as fast as an NI-3100 and about 2.25x faster than an NI-3000.
Jeff -
I don't see how TRUE and FALSE could run any faster than 1 and 0. TRUE and FALSE are constants which have the assigned values 1 and 0. I expect that at compile time TRUE and FALSE are replaced and that the token file is the same as if 1 and 0 had been entered. Don't know that for a fact, but that's my understanding of how constants are handled.
-
I agree, that's my understanding also.I don't see how TRUE and FALSE could run any faster than 1 and 0. TRUE and FALSE are constants which have the assigned values 1 and 0. I expect that at compile time TRUE and FALSE are replaced and that the token file is the same as if 1 and 0 had been entered. Don't know that for a fact, but that's my understanding of how constants are handled. -
I don't see how TRUE and FALSE could run any faster than 1 and 0. TRUE and FALSE are constants which have the assigned values 1 and 0. I expect that at compile time TRUE and FALSE are replaced and that the token file is the same as if 1 and 0 had been entered. Don't know that for a fact, but that's my understanding of how constants are handled.
That is what I thought, the only thing I can think of is that maybe TRUE and FALSE are treated as boolean instead of integers? Or maybe the compiler is doing some sort of optimization on them.... or maybe my testing is flawed
I just finished playing HVAC guy (had to run a new wire to the roof top unit to hook the new Viewstat... 4 wires is just not enough
). I'm going to try to change the test method now.
Jeff -
Ok, here are the results using GET_TIMER:
Line 1 (18:24:28):: ********************************************************* Line 2 (18:24:28):: * TEST 8 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 3 (18:24:28):: * Most recent 5 runs: Line 4 (18:24:28):: * 1: 20 Line 5 (18:24:28):: * 2: 21 Line 6 (18:24:28):: * 3: 20 Line 7 (18:24:28):: * 4: 20 Line 8 (18:24:28):: * 5: 20 Line 9 (18:24:28):: *---------------------------------------------------------- Line 10 (18:24:28):: * Average run time: 20ms - over 5 tests Line 11 (18:24:28):: ********************************************************* Line 12 (18:24:28):: ********************************************************* Line 13 (18:24:28):: * TEST 9 REPORT: nInfo[nLoop]=1 .. nInfo[nLoop]=0 Line 14 (18:24:28):: * Most recent 5 runs: Line 15 (18:24:28):: * 1: 20 Line 16 (18:24:28):: * 2: 20 Line 17 (18:24:28):: * 3: 21 Line 18 (18:24:28):: * 4: 21 Line 19 (18:24:28):: * 5: 21 Line 20 (18:24:28):: *---------------------------------------------------------- Line 21 (18:24:28):: * Average run time: 20ms - over 5 tests Line 22 (18:24:28):: ********************************************************* Line 23 (18:24:28):: ********************************************************* Line 24 (18:24:28):: * TEST 10 REPORT: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 25 (18:24:28):: * Most recent 5 runs: Line 26 (18:24:28):: * 1: 19 Line 27 (18:24:28):: * 2: 19 Line 28 (18:24:28):: * 3: 19 Line 29 (18:24:28):: * 4: 19 Line 30 (18:24:28):: * 5: 19 Line 31 (18:24:28):: *---------------------------------------------------------- Line 32 (18:24:28):: * Average run time: 19ms - over 5 tests Line 33 (18:24:28):: *********************************************************
I think I see the problem and the reason I wound up using timelines. Timelines have a higher resolution than GET_TIMER. GET_TIMER has a resolution of only .1 seconds. Timelines allow for .001 seconds. Here is a sample of both methods head to head:Line 193 (18:41:10):: ********************************************************* Line 194 (18:41:10):: * TEST 8 STARTING: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 195 (18:41:10):: ********************************************************* Line 196 (18:41:10):: ********************************************************* Line 197 (18:41:10):: * TEST 8 FINISHED: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 198 (18:41:10):: * Last run time: 1 - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 199 (18:41:10):: * Average run time: 0 - over 5 tests - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 200 (18:41:10):: ********************************************************* Line 201 (18:41:10):: ********************************************************* Line 202 (18:41:10):: * TEST 9 STARTING: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 203 (18:41:10):: ********************************************************* Line 204 (18:41:10):: ********************************************************* Line 205 (18:41:10):: * TEST 9 FINISHED: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 206 (18:41:10):: * Last run time: 0 - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 207 (18:41:10):: * Average run time: 0 - over 5 tests - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 208 (18:41:10):: ********************************************************* Line 209 (18:41:10):: ********************************************************* Line 210 (18:41:10):: * TEST 10 STARTING: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 211 (18:41:10):: ********************************************************* Line 212 (18:41:12):: ********************************************************* Line 213 (18:41:12):: * TEST 10 FINISHED: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 214 (18:41:12):: * Last run time: 20 - ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 215 (18:41:12):: * Average run time: 19 - over 5 tests - ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 216 (18:41:12):: ********************************************************* Line 217 (18:41:12):: ********************************************************* Line 218 (18:41:12):: * TEST 11 STARTING: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 219 (18:41:12):: ********************************************************* Line 220 (18:41:12):: ********************************************************* Line 221 (18:41:12):: * TEST 11 FINISHED: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 222 (18:41:12):: * Last run time: 29ms - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 223 (18:41:12):: * Average run time: 28ms - over 5 tests - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 224 (18:41:12):: ********************************************************* Line 225 (18:41:12):: ********************************************************* Line 226 (18:41:12):: * TEST 12 STARTING: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 227 (18:41:12):: ********************************************************* Line 228 (18:41:12):: ********************************************************* Line 229 (18:41:12):: * TEST 12 FINISHED: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 230 (18:41:12):: * Last run time: 43ms - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 231 (18:41:12):: * Average run time: 43ms - over 5 tests - nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 232 (18:41:12):: ********************************************************* Line 233 (18:41:12):: ********************************************************* Line 234 (18:41:12):: * TEST 13 STARTING: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 235 (18:41:12):: ********************************************************* Line 236 (18:41:14):: ********************************************************* Line 237 (18:41:14):: * TEST 13 FINISHED: ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 238 (18:41:14):: * Last run time: 1920ms - ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 239 (18:41:14):: * Average run time: 1917ms - over 5 tests - ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]] Line 240 (18:41:14):: *********************************************************
Tests 8, 9, and 10 are done with GET_TIMER. 11,12, and 13 are done with timelines. Tests 8, 9, 11, and 12 are identical in what they are doing. Tests 8 and 11 are looped 1000 times, tests 9 and 12 are looped 1500 times.
I will post the code so a second set of eyes can see if I am missing something.
Jeff
ADDED:
Here is another set of results. This time I ran the loops 10000 times for the first set and 12000 for the second set.Line 561 (19:15:45):: ********************************************************* Line 562 (19:15:45):: * TEST 8 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 563 (19:15:45):: * Most recent 5 runs: Line 564 (19:15:45):: * 1: 4 Line 565 (19:15:45):: * 2: 4 Line 566 (19:15:45):: * 3: 4 Line 567 (19:15:45):: * 4: 4 Line 568 (19:15:45):: * 5: 3 Line 569 (19:15:45):: *---------------------------------------------------------- Line 570 (19:15:45):: * Average run time: 3 - over 5 tests Line 571 (19:15:45):: ********************************************************* Line 572 (19:15:45):: ********************************************************* Line 573 (19:15:45):: * TEST 9 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 574 (19:15:45):: * Most recent 5 runs: Line 575 (19:15:45):: * 1: 4 Line 576 (19:15:45):: * 2: 4 Line 577 (19:15:45):: * 3: 5 Line 578 (19:15:45):: * 4: 5 Line 579 (19:15:45):: * 5: 5 Line 580 (19:15:45):: *---------------------------------------------------------- Line 581 (19:15:45):: * Average run time: 4 - over 5 tests Line 582 (19:15:45):: ********************************************************* Line 594 (19:15:45):: ********************************************************* Line 595 (19:15:45):: * TEST 11 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 596 (19:15:45):: * Most recent 5 runs: Line 597 (19:15:45):: * 1: 362ms Line 598 (19:15:45):: * 2: 363ms Line 599 (19:15:45):: * 3: 362ms Line 600 (19:15:45):: * 4: 362ms Line 601 (19:15:45):: * 5: 363ms Line 602 (19:15:45):: *---------------------------------------------------------- Line 603 (19:15:45):: * Average run time: 362ms - over 5 tests Line 604 (19:15:45):: ********************************************************* Line 605 (19:15:45):: ********************************************************* Line 606 (19:15:45):: * TEST 12 REPORT: nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE Line 607 (19:15:45):: * Most recent 5 runs: Line 608 (19:15:45):: * 1: 435ms Line 609 (19:15:45):: * 2: 434ms Line 610 (19:15:45):: * 3: 434ms Line 611 (19:15:45):: * 4: 435ms Line 612 (19:15:45):: * 5: 435ms Line 613 (19:15:45):: *---------------------------------------------------------- Line 614 (19:15:45):: * Average run time: 434ms - over 5 tests Line 615 (19:15:45):: *********************************************************
-
Ok, here is the code I am running for the tests. Take a look and let me know if I am overlooking something very obvious. Keep in mind, the report function has not been changed to distinguish between the two test types and simply appends ms to the times.
PROGRAM_NAME='MultipleTests' DEFINE_DEVICE dvTP = 10001:1:0 DEFINE_CONSTANT //Benchmark Constants integer MAX_NUM_TESTS = 20; DEFINE_CONSTANT//Place test constants below DEFINE_TYPE //Place Test Types here DEFINE_VARIABLE //Benchmark Variables DO NOT CHANGE char sTestDescription[MAX_NUM_TESTS][50] VOLATILE LONG lTL_Times[5] = {10000,10000,10000,10000,10000} LONG lTestTime[MAX_NUM_TESTS][6] //1-5 = last values, 6 = running avg of all LONG lTestTimeStart[MAX_NUM_TESTS][6] //1-5 = last values, 6 = running avg of all LONG lTestTimeFinish[MAX_NUM_TESTS][6] //1-5 = last values, 6 = running avg of all LONG lTestAverageCount[MAX_NUM_TESTS] = 0 VOLATILE INTEGER nTestIndex[MAX_NUM_TESTS] VOLATILE INTEGER nWORK_IN_PROGRESS[MAX_NUM_TESTS] define_variable //Place Test Variables here volatile LONG nInfo[70000] LONG nLoop LONG nMax LONG Value1 = 1000; Long Value2 = 1500; //********************** //Benchmark functions. //Call the TestStart function immediately before code to be tested. //Call the TestFinish function immediately after code to be tested. //********************** define_function TestName(integer nMethod, char sName[50]){ sTestDescription[nMethod] = sName; } define_function TestReset(integer nMethod){//Clears averages and sets pointers to first spot. stack_var integer x; nTestIndex[nMethod] = 1; nWORK_IN_PROGRESS[nMethod] = 0; timeline_kill(nMethod); lTestAverageCount[nMethod] = 0; for(x=6;x;x--){ lTestTime[nMethod][x] = 0; } send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(nMethod),' RESET: ',sTestDescription[nMethod]"; send_string 0,"'*********************************************************'"; } define_function TestStart(integer nMethod){ IF((nTestIndex[nMethod] > 5) or (nTestIndex[nMethod] < 1)) nTestIndex[nMethod] = 1; send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(nMethod),' STARTING: ',sTestDescription[nMethod]"; send_string 0,"'*********************************************************'"; nWork_In_Progress[nMethod] = 1; lTestTimeStart[nMethod][nTestIndex[nMethod]] = GET_TIMER; // TIMELINE_CREATE(type_cast(nMethod),lTL_Times,5,TIMELINE_RELATIVE,TIMELINE_REPEAT); } define_function TestFinish(integer nMethod){ lTestTimeFinish[nMethod][nTestIndex[nMethod]] = GET_TIMER; // TIMELINE_PAUSE(nMethod); lTestTime[nMethod][nTestIndex[nMethod]] = lTestTimeFinish[nMethod][nTestIndex[nMethod]] - lTestTimeStart[nMethod][nTestIndex[nMethod]]; // TIMELINE_KILL(nMethod); lTestTime[nMethod][6] = ((lTestTime[nMethod][6]*lTestAverageCount[nMethod]) + lTestTime[nMethod][nTestIndex[nMethod]])/(lTestAverageCount[nMethod] + 1); lTestAverageCount[nMethod]++; send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(nMethod),' FINISHED: ',sTestDescription[nMethod]"; send_string 0,"'* Last run time: ',itoa(lTestTime[nMethod][nTestIndex[nMethod]]/10),'.',itoa(lTestTime[nMethod][nTestIndex[nMethod]]%10),'sec - ',sTestDescription[nMethod]"; send_string 0,"'* Average run time: ',itoa(lTestTime[nMethod][6]/10),'.',itoa(lTestTime[nMethod][6]%10),'sec - over ',itoa(lTestAverageCount[nMethod]),' tests - ',sTestDescription[nMethod]"; send_string 0,"'*********************************************************'"; IF((nTestIndex[nMethod] >= 5) or (nTestIndex[nMethod] < 1)) nTestIndex[nMethod] = 1; ELSE nTestIndex[nMethod]++; nWORK_IN_PROGRESS[nMethod] = 0; } define_function TestStart2(integer nMethod){ IF((nTestIndex[nMethod] > 5) or (nTestIndex[nMethod] < 1)) nTestIndex[nMethod] = 1; send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(nMethod),' STARTING: ',sTestDescription[nMethod]"; send_string 0,"'*********************************************************'"; nWork_In_Progress[nMethod] = 1; // lTestTimeStart[nMethod][nTestIndex[nMethod]] = GET_TIMER; TIMELINE_CREATE(type_cast(nMethod),lTL_Times,5,TIMELINE_RELATIVE,TIMELINE_REPEAT); } define_function TestFinish2(integer nMethod){ // lTestTimeFinish[nMethod][nTestIndex[nMethod]] = GET_TIMER; TIMELINE_PAUSE(nMethod); lTestTime[nMethod][nTestIndex[nMethod]] = TIMELINE_GET(nMethod); TIMELINE_KILL(nMethod); lTestTime[nMethod][6] = ((lTestTime[nMethod][6]*lTestAverageCount[nMethod]) + lTestTime[nMethod][nTestIndex[nMethod]])/(lTestAverageCount[nMethod] + 1); lTestAverageCount[nMethod]++; send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(nMethod),' FINISHED: ',sTestDescription[nMethod]"; send_string 0,"'* Last run time: ',itoa(lTestTime[nMethod][nTestIndex[nMethod]]),'ms - ',sTestDescription[nMethod]"; send_string 0,"'* Average run time: ',itoa(lTestTime[nMethod][6]),'ms - over ',itoa(lTestAverageCount[nMethod]),' tests - ',sTestDescription[nMethod]"; send_string 0,"'*********************************************************'"; IF((nTestIndex[nMethod] >= 5) or (nTestIndex[nMethod] < 1)) nTestIndex[nMethod] = 1; ELSE nTestIndex[nMethod]++; nWORK_IN_PROGRESS[nMethod] = 0; } define_function TestPrintReport(integer nMethod){ stack_var integer x; if(nMethod){ send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(nMethod),' REPORT: ',sTestDescription[nMethod]"; send_string 0,"'* Most recent 5 runs:'"; send_string 0,"'* 1: ',itoa(lTestTime[nMethod][1]),'ms'"; send_string 0,"'* 2: ',itoa(lTestTime[nMethod][2]),'ms'"; send_string 0,"'* 3: ',itoa(lTestTime[nMethod][3]),'ms'"; send_string 0,"'* 4: ',itoa(lTestTime[nMethod][4]),'ms'"; send_string 0,"'* 5: ',itoa(lTestTime[nMethod][5]),'ms'"; send_string 0,"'*----------------------------------------------------------'"; send_string 0,"'* Average run time: ',itoa(lTestTime[nMethod][6]),'ms - over ',itoa(lTestAverageCount[nMethod]),' tests'"; send_string 0,"'*********************************************************'"; } else{ for(x=1;x<=MAX_NUM_TESTS;x++){ if(lTestTime[x][1]){ send_string 0,"'*********************************************************'"; send_string 0,"'* TEST ',itoa(x),' REPORT: ',sTestDescription[x]"; send_string 0,"'* Most recent 5 runs:'"; send_string 0,"'* 1: ',itoa(lTestTime[x][1]),'ms'"; send_string 0,"'* 2: ',itoa(lTestTime[x][2]),'ms'"; send_string 0,"'* 3: ',itoa(lTestTime[x][3]),'ms'"; send_string 0,"'* 4: ',itoa(lTestTime[x][4]),'ms'"; send_string 0,"'* 5: ',itoa(lTestTime[x][5]),'ms'"; send_string 0,"'*----------------------------------------------------------'"; send_string 0,"'* Average run time: ',itoa(lTestTime[x][6]),'ms - over ',itoa(lTestAverageCount[x]),' tests'"; send_string 0,"'*********************************************************'"; } } } } DEFINE_FUNCTION PutYourFunctionsBelow(){ //example function for testing TestName(20,'Sample Test');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(20); //Test code goes here! TestFinish(20); } DEFINE_FUNCTION forLoop1(){ TestName(1,'FOR (nLoop = 1; nLoop <= LENGTH_ARRAY(nInfo); nLoop++)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(1); FOR (nLoop = 1; nLoop <= LENGTH_ARRAY(nInfo); nLoop++) { nInfo[nLoop] = 1; } TestFinish(1); } DEFINE_FUNCTION forLoop2(){ TestName(3,'FOR (nLoop = 1; nLoop <= MAX_LENGTH_ARRAY(nInfo); nLoop++)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(3); FOR (nLoop = 1; nLoop <= MAX_LENGTH_ARRAY(nInfo); nLoop++) { nInfo[nLoop] = 2; } TestFinish(3); } DEFINE_FUNCTION forLoop3(){ TestName(4,'FOR (nLoop = 1, nMax = MAX_LENGTH_ARRAY(nInfo); nLoop <= nMax; nLoop++)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(4); FOR (nLoop = 1, nMax = MAX_LENGTH_ARRAY(nInfo); nLoop <= nMax; nLoop++) { nInfo[nLoop] = 4; } TestFinish(4); } DEFINE_FUNCTION forLoop4(){ TestName(5,'FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop > 0; nLoop--)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(5); FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop > 0; nLoop--) { nInfo[nLoop] = 8 } TestFinish(5); } DEFINE_FUNCTION forLoop5(){ TestName(6,'FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop; nLoop--)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(6); FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop; nLoop--) { nInfo[nLoop] = 16 } TestFinish(6); } DEFINE_FUNCTION forLoop6(){ stack_var long snLoop; TestName(7,'FOR (snLoop = MAX_LENGTH_ARRAY(nInfo); snLoop; snLoop--)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(7); FOR (snLoop = MAX_LENGTH_ARRAY(nInfo); snLoop; snLoop--) { nInfo[snLoop] = 32 } TestFinish(7); } DEFINE_FUNCTION forLoop7(){ stack_var long snLoop; TestName(2,'FOR (snLoop = 1; snLoop <= LENGTH_ARRAY(nInfo); snLoop++)');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(2); FOR (snLoop = 1; snLoop <= LENGTH_ARRAY(nInfo); snLoop++) { nInfo[snLoop] = 64; } TestFinish(2); } DEFINE_FUNCTION onVsTrue(){ stack_var long snLoop; TestName(8,'nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(8); FOR (nLoop = Value1; nLoop; nLoop--) { nInfo[nLoop] = TRUE; nInfo[nLoop] = FALSE; } TestFinish(8); TestName(9,'nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(9); FOR (nLoop = Value2; nLoop; nLoop--) { nInfo[nLoop] = TRUE;//1; nInfo[nLoop] = FALSE;//0; } TestFinish(9); TestName(10,'ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]]');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart(10); FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop; nLoop--) { ON[nInfo[nLoop]]; OFF[nInfo[nLoop]]; } TestFinish(10); TestName(11,'nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart2(11); FOR (nLoop = Value1; nLoop; nLoop--) { nInfo[nLoop] = TRUE; nInfo[nLoop] = FALSE; } TestFinish2(11); TestName(12,'nInfo[nLoop]=TRUE .. nInfo[nLoop]=FALSE');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart2(12); FOR (nLoop = Value2; nLoop; nLoop--) { nInfo[nLoop] = TRUE;//1; nInfo[nLoop] = FALSE;//0; } TestFinish2(12); TestName(13,'ON[nInfo[nLoop]] .. OFF[nInfo[nLoop]]');//20 is the test ID. Change this accordingly. start at 1. MAX_NUM_TESTS is the highest ID allowed. TestStart2(13); FOR (nLoop = MAX_LENGTH_ARRAY(nInfo); nLoop; nLoop--) { ON[nInfo[nLoop]]; OFF[nInfo[nLoop]]; } TestFinish2(13); } DEFINE_START SET_LENGTH_ARRAY (nInfo,70000) DEFINE_EVENT BUTTON_EVENT[dvTP,1] { //Run Test PUSH: { stack_var integer x; for(x=5;x;x--){ forLoop1(); forLoop2(); forLoop3(); forLoop4(); forLoop5(); forLoop6(); forLoop7(); onVsTrue(); } } } BUTTON_EVENT[dvTP,2] { //Run Test PUSH: { stack_var integer x; for(x=5;x;x--){ onVsTrue(); } } } BUTTON_EVENT[dvTP,3] { //Run Test PUSH: { } } BUTTON_EVENT[dvTP,100] BUTTON_EVENT[dvTP,101] BUTTON_EVENT[dvTP,102] BUTTON_EVENT[dvTP,103] BUTTON_EVENT[dvTP,104] BUTTON_EVENT[dvTP,105] BUTTON_EVENT[dvTP,106] BUTTON_EVENT[dvTP,107] BUTTON_EVENT[dvTP,108] BUTTON_EVENT[dvTP,109] BUTTON_EVENT[dvTP,110] BUTTON_EVENT[dvTP,111] BUTTON_EVENT[dvTP,112] BUTTON_EVENT[dvTP,113] BUTTON_EVENT[dvTP,114] BUTTON_EVENT[dvTP,115] BUTTON_EVENT[dvTP,116] BUTTON_EVENT[dvTP,117] BUTTON_EVENT[dvTP,118] BUTTON_EVENT[dvTP,119] BUTTON_EVENT[dvTP,120]{ //Print reports. channel 100 prints all valid reports. //channel 101-120 print a report only for a single test (channel-100) PUSH: { TestPrintReport(button.input.channel - 100); } } button_event[dvTp,255]{ //Reset Test Data push:{ stack_var integer x; for(x=MAX_NUM_TESTS;x;x--){ TestReset(x); } } }
Jeff -
Netlinx doesn?t support a Boolean data type. TRUE and FALSE are declared as CHARs in Netlinx.axi. I changed the variable nVar in my test program from an INTEGER to a CHAR and it made absolutely no difference in the results.Spire_Jeff wrote:That is what I thought, the only thing I can think of is that maybe TRUE and FALSE are treated as boolean instead of integers?Spire_Jeff wrote:I think I see the problem and the reason I wound up using timelines. Timelines have a higher resolution than GET_TIMER. GET_TIMER has a resolution of only .1 seconds. Timelines allow for .001 seconds
I don?t feel loops that only last milliseconds collect anywhere near enough data to draw solid conclusions. The FOR loops I tested with were 1 million times round trip When tests last for 20 seconds plus, measuring to the tenth of a second or to a thousand of a second doesn?t make much of a difference. If my math is correct that?s about ? of 1 percent possible margin of difference or at most ? of 1 percent.Spire_Jeff wrote:Tests 8 and 11 are looped 1000 times, tests 9 and 12 are looped 1500 times.
If your test methods still support that 1/0 is slower than TRUE/FALSE, I just can?t buy it. I also believe the simpler and least obstructive testing method works best. We?ll simply have to agree to disagree.
Whatever the case, I?m not going to be afraid to use ON/OFF, TRUE/FALSE, or 1/0 because all we?re really doing in the big scheme of things is contesting (discussing) at most a drop of water in the ocean with this one. It sure isn?t going to make any difference in your code that takes 25 minutes to boot.
Man that?s over the top crazy unless you have a boat load of Duet modules in that program, even still...
Leave a Comment
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums

