LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

VISA Read function slower for USB VCP than "real" serial port

Solved!
Go to solution

@Edjsch wrote:

Jeff,

 

BTW, if I highlight execution I can see that what I said in my previous post is correct. All of my code outside the While loop executes before the code within the loop. The code in the While loop then does execute in a quasi-random order (that is, "random" except when forced to execute in a specific order determined by the wiring), but the same every time.

 

Ed


That is an incorrect assumption.  When you turn on highlight execution all code is executed in the UI Thread there is only one thread and no multithreading is possible. (But we can let that go for now.)


"Should be" isn't "Is" -Jay
0 Kudos
Message 91 of 109
(835 Views)

Jeff,

 

I know we're off topic (how serious an infraction is this?), but are you saying that the compiler would put code (code exclusive of loops, of course, because those loops could be executed in unpredictable order and themselves be subject to multi-threading; just simple initializing code) outside all loops in more than one thread? I find this inconceivable. There's little or no reason to do this, I think. If you can give an example, please do so.

 

Ed

0 Kudos
Message 92 of 109
(829 Views)

you are the OP so no infraction.

 

No data dependancy = unique thread. LabVIEW in natively multi threading and will spawn a new thread unless there is data dependancy.  There is tremendous reason to do this as it is foundational to dataflow programming languages.


"Should be" isn't "Is" -Jay
0 Kudos
Message 93 of 109
(826 Views)

Jeff,

 

Thanks for the explanation. So if we were to initialize 100 variables (assuming different data types for the moment), LV would spawn multiple threads? What about if you were initializing, say 100 I32's to 0 (0 was wired to all)?

 

However, this discussion seems irrelevant in my code because my Initial Timer gets initialized BEFORE the While loop is entered. And my RPS calculation (the division) is dependent on reading the current timer (Tick Count vi), subtracting the Initial Timer and passing that to the Divide vi in that specific order. And the divide, in turn, is dependent on detecting the LF character of the string read. No?

 

Ed

0 Kudos
Message 94 of 109
(817 Views)

What about if you were initializing, say 100 I32's to 0 (0 was wired to all)?

 

LabVIEW would Read the Constant of 0 create 100 copies of it in 100 different buffers in memory and pass the 100 buffers to the 100 I32 terminals.  Untill the Optomizer showed up a few years ago (since 100 copies isn't really effecient) the optomizer would peek into the BD at compile time and say "Hey= I can replace all that with constant folding since the outcome of the operation can never change."  this is probably also true of your write to the terminal, it never read the constant just preloaded the terminal with value=0

 

Data Flow Data Flow Data flow.  once all inputs are available the code can run whenever the OS schedules the thread.  Bear in mind any thread can normally be interupted or suspended if the OS gets a higher priority task so, unless you do something to garantee that a piece of code will run with Subrutine priority your can't even say the code will execute atomically.


"Should be" isn't "Is" -Jay
0 Kudos
Message 95 of 109
(808 Views)

Jeff,

 

Thanks. To expand on this, if I create a vi with a While loop without any Wait and run it, the CPU usage on my PC (dual core) skyrockets to 55 – 60% (using my test vi, Serial Read (Max RPS test).vi). If I add just a 1 ms Wait, then the CPU usage drops to 0 – 1%, as when my system is idle. This is why NI recommends at least a 1 mS Wait (or Wait Until Next ms Multiple) in the main loop of a vi.

 

Say I run multiple instances of a looping-without-wait vi (no VISA Reads), even more processor time will be consumed, I imagine (I did not try). Then if I run my Serial Read (Max RPS test).vi concurrently, would the performance of the VISA Read function remain the same or not? For example, with the SiLabs driver we see with Portmon 4 – 5 mS delays around the reads, and about 2 microseconds with the 2 other drivers I've mentioned. I suspect that since the VISA-driver interactions are at the kernel level, they would get high priority and would perform about the same (until the CPU was really choked, I suppose). Do you agree? (Note that my test vi does not perform any better with my 250 RPS test with 0 Wait compared to a Wait of 1 mS.)

 

Ed

0 Kudos
Message 96 of 109
(803 Views)

Thanks. To expand on this, if I create a vi with a While loop without any Wait and run it, the CPU usage on my PC (dual core) skyrockets to 55 – 60% (Probably ove 95% on one of the cores) (using my test vi, Serial Read (Max RPS test).vi). If I add just a 1 ms Wait, then the CPU usage drops to 0 – 1%, as when my system is idle. This is why NI recommends at least a 1 mS Wait (or Wait Until Next ms Multiple) in the main loop of a vi  (Slightly miss-stated.  no greedy loops that perform IO [ File/ Hardware/ user])  This is essentially correct although I don't think any programming language used for user applications considers writing greedy loops good practice- it is a good way to waste processor power and your program won't play nice or get along well with others.

 

 

Say I run multiple instances of a looping-without-wait vi (no VISA Reads), even more processor time will be consumed, Right up to 99.99% then the loops cycle time will slow down instead of higher processor usage- But it's not a right angle graph the OS tries to prevent a deadlock by playing with processes   would the performance of the VISA Read function remain the same or not? It would be effected negativly 

 

Do you agree? (Note that my test vi does not perform any better with my 250 RPS test with 0 Wait compared to a Wait of 1 mS.)

 

Yes however, A wait of 0 ms is not that same as a loop with no wait and you seam to use those terms interchangably.  a 0ms wait forces the executing thread to release - if no one else is higher in priority the thread may re-aquire and procede so, It is not "Greedy".   Please don't ask about a loop with 0ms wait and subroutine priority.  First I wouldn't write a loop like that (IO that is time CRITICAL needs a different OS) second I don't know. (Perhaps the universe explodes- I won't risk triingSmiley Very Happy -I hate it when the universe explodes and its MY faultSmiley Embarassed)

 

 

This is why I asked about Device Manager and Measurment and Automation Explorer port settings- I wonder if a setting that is time intensive but usually needs to be done infrequently (like setting Baud rate on every call rather than 1 time only) or some other goofball thing that is specific to the VISA layer and the SiLabs driver or even to only the specific VISA session class and this driver.  (The hint is that HyperTerm works- VISA has issues that are hard to duplicate.)


"Should be" isn't "Is" -Jay
0 Kudos
Message 97 of 109
(796 Views)

Jeff,

 

The help for the Wait (ms) vi says: “Wiring a value of 0 to the milliseconds to wait input forces the current thread to yield control of the CPU.” At first glance this looks backwards to me: Wiring a 0 gives me the same CPU usage results as deleting the Wait vi totally. (This is why I use them interchangeably, as you noted.) To me the Wait is simply a “sleep” function in a RTOS environment. Wiring a 1 tells the thread to sleep for 1 mS, yielding to the CPU that amount of time. Wiring a 0, on the other hand, my first thought would be not to yield any time to the CPU, hog as you say. But what you point out makes sense: The thread yields to the CPU, but then the CPU gives itself (usually) right back to the thread. In effect this permits the OS to determine how much time to give to the application. In my case on my dual-core PC, it’s normally (usually) about 55 – 60%.

 

I don’t think the OS would ever yield 99.99% to applications. It needs to reserve CPU time for kernel stuff and running the UI itself. I don’t know how much, but 99.99% seems way too high. I could test by building an exe of the vi with 0 Wait, and see how much each instance running adds to the CPU usage. I'll bet it doesn't climb too much above the 60% max that I see. But this is neither here nor there.

 

On your last paragraph: This is why I have theVISAConfigureSerialPort vi outside the main loop, as it should be. Newbies tend to put a While loop around the Basic Serial Write and Read vi example (I know I did initially), but then the port is continually getting configured. Not needed. (Alternatively it could be put inside the main loop, but put it inside a Case structure with I = 1 wired to its selector input.) From the Portmon logs, the reason that HyperTerminal keeps up (at 250 RPS anyway) is that it is reading 80 bytes per read, not the Bytes at Port as I am. (I’ve tried wiring different numbers to the Bytes to Read input, but that works worse.)

 

Ed

0 Kudos
Message 98 of 109
(788 Views)

You misunderstood what I'm suggesting with this

"

This is why I asked about Device Manager and Measurment and Automation Explorer port settings- I wonder if a setting that is time intensive but usually needs to be done infrequently (like setting Baud rate on every call rather than 1 time only) or some other goofball thing that is specific to the VISA layer and the SiLabs driver or even to only the specific VISA session class and this driver.  (The hint is that HyperTerm works- VISA has issues that are hard to duplicate.)

"

 

I'm looking for a Bug in how VISA interacts with Silabser.  Not poor coding in LabVIEW


"Should be" isn't "Is" -Jay
0 Kudos
Message 99 of 109
(782 Views)

Jeff,

 

Initially I thought too that there might be a bug in VISA, but now I think not. I think the bug (really poor coding) is in the SiLabs driver because other drivers work as expected, with over 1000 times shorter delays (time stamps) around the reads (at least that's what the Portmon logs show).

 

Ed

0 Kudos
Message 100 of 109
(779 Views)