Jump to content

Explanation of LabVIEW Execution Systems and Thread Priorities


Recommended Posts

Hi All,

I'm looking for a good resource that explains LabVIEW's Execution System / Thread Allocation / Thread Priority system.

As a background to the reason for my request:

I have an application with over 50 parallel loops running at fixed but configurable times. Twenty of these loops are calling a .net Dll and are thus not in a Timed Loop (there is a known issue according to NI support with calling a .net dll in a timed loop where the call time is large ie. upwards of a second). The remaining loops are performing other data acquisition. Each loop is what I call a Task Controller - it looks after a specific piece of hardware, taking requests for data (via queues), performing data acquisition and then pumping the result back to the requester. In order to seperate the timing of the functionality (and allow multiple requesters access to the same data), this process is not sequential but occurs in parallel loops.

So there is a lot of parallel activity going on. I notice that as more of these loops fire up, the slower the remaining loops are. The CPU usage tends to stay around 7-8% during this time irrespective of how many loops are executing. Note that the .net dll calls (up to 20) are reasonably slow calls and each could take up to 6 seconds to execute. The .net dll has been written to handle multi-threading. The PC is a hyper-threaded quad core (ie 8 logical cores) @ 3.3GHz. Kinda a meaty machine.

I should also mention that the majority of the VIs are re-entrant. The only non-rentrant VIs are some FGVs and a few User Interface VIs that reference the data in these FGVs. And before you ask the FGVs are simply Get/Set for a handful of cluster points.

So I figure it's a simple case of thread starvation. Every VI is currently set to the Standard Execution System (via Same as Caller) with Normal Priority. I figure that adjusting these settings on the top level Task Controller vis may assist in spreading the load to the remaining available, but not executing, threads. The SubVIs under each Task Controller will continue to use the Same As Caller setting, allowing me to seperate logically each Task into appropriate Execution Systems.

Any thoughts?

Edited by ak_nz
Link to comment

Start with NI's article "How Many Threads Does LabVIEW Allocate?"

Also see the LabVIEW help for "Multitasking, Multithreading, and Multiprocessing."

If you divide your code across execution systems instead of leaving them all at "Same as Caller" you should see the work distributed across more threads, and probably better performance and higher CPU use.

Link to comment

I think you'll need at least one thread for every .NET DLL call you want to run asynchronously to avoid blocking by the .NET DLL calls. LabVIEW can schedule multiple activities on one thread for internal calls so if a VI goes dormant while waiting that thread can be reassigned to another as long as all of the code is native LabVIEW. This isn't true for DLL calls. LabVIEW can't reuse the thread assigned to the .NET call and must wait for it to return. So as soon as there are more .NET calls than threads assigned for the execution system they run in, someone has to wait. You can set the number of threads per execution system using the vi.lib\Utility\sysinfo.llb\threadconfig.vi referenced in the first link Ned pointed to. If you need more threads than can be assigned to one execution system, then you may have to split the .NET calls across multiple execution systems.

Mark

Link to comment

Another tangential resource, does have some related info IIRC: NI LabVIEW Compiler: Under the Hood

If you divide your code across execution systems instead of leaving them all at "Same as Caller" you should see the work distributed across more threads, and probably better performance and higher CPU use.

Because the default for every VI is "Same as Caller", the top-level VI will have this same configuration (unless you change it). I believe (though can't substantiate it right now) that parallel activities will be scheduled amongst the available execution systems if no preference has been set. I'll see if I can figure out where I got that from. It would be great if someone from NI could specifically address that point.

Link to comment

Thanks everyone for your posts.

The solution I have run with is separating the tasks out into each execution system. In particular, I placed only the tasks with .net calls into the "Other 2" execution system and specified, by the configuration ini file, for 20 threads at Normal priority (there are 20 maximum simultaneous calls to the dll) for this ES. I added this as a Post-build action in the executable build configuration to automate that process.

This has fractionally increased CPU loading by a few percent as expected but also allowed all the remaining tasks to operate within their required timings (ie. now properly "insulated" from the dll calls). So it would appear the .net dll calls were consuming all available threads, as suggested by Mark Smith.

I'll dig deeper into seeing if I can improve the performance any further (ie. via tweaking VI priorities) but this helps me out for now, thanks all for your help!

Link to comment

Thanks everyone for your posts.

The solution I have run with is separating the tasks out into each execution system. In particular, I placed only the tasks with .net calls into the "Other 2" execution system and specified, by the configuration ini file, for 20 threads at Normal priority (there are 20 maximum simultaneous calls to the dll) for this ES. I added this as a Post-build action in the executable build configuration to automate that process.

This has fractionally increased CPU loading by a few percent as expected but also allowed all the remaining tasks to operate within their required timings (ie. now properly "insulated" from the dll calls). So it would appear the .net dll calls were consuming all available threads, as suggested by Mark Smith.

I'll dig deeper into seeing if I can improve the performance any further (ie. via tweaking VI priorities) but this helps me out for now, thanks all for your help!

The maximum is 8 per execution system, per priority. You can get your twenty by spreading them over 3 execution systems (for normal priority)

Link to comment

The maximum is 8 per execution system, per priority. You can get your twenty by spreading them over 3 execution systems (for normal priority)

Hi ShaunR. Is this figure of 8 independent of CPU core count (ie. in my case I have 8 logical cores)? The reason I ask is that the threadconfig.vi in the sysinfo.llb allows me to specify up to 20 threads in each combination of execution system and priority. I might be understanding this wrong, maybe this ability in threadconfig.vi is misleading? On my machine all the table entries were set to 8 initially as you suggested.

Or is this a case of a single thread, per execution system, per priority per CPU core (hence the default of 8 in the tables on my machine)?

Link to comment

Hi ShaunR. Is this figure of 8 independent of CPU core count (ie. in my case I have 8 logical cores)? The reason I ask is that the threadconfig.vi in the sysinfo.llb allows me to specify up to 20 threads in each combination of execution system and priority. I might be understanding this wrong, maybe this ability in threadconfig.vi is misleading? On my machine all the table entries were set to 8 initially as you suggested.

Or is this a case of a single thread, per execution system, per priority per CPU core (hence the default of 8 in the tables on my machine)?

Hmmm. In 2009 and 2010 it was max 8 per exec, per priority irrespective of the number of cores. Max 200+1 in total.

I've just looked in 2011 (I rarely use it) and indeed you seem to be right; you can set 20. However, it can be set to 20 on both my Quad core (8) and my dual core (4) so I think they just bumped up the limit rather than made it scalable in accordance with number of cores.

Edited by ShaunR
  • Like 1
Link to comment

Hmmm. In 2009 and 2010 it was max 8 per exec, per priority irrespective of the number of cores. Max 200+1 in total.

I've just looked in 2011 (I rarely use it) and indeed you seem to be right; you can set 20. However, it can be set to 20 on both my Quad core (8) and my dual core (4) so I think they just bumped up the limit rather than made it scalable in accordance with number of cores.

OK, very useful to know; I'll bear that in mind for some of our legacy projects running in 2009/2010. Thanks!

Edited by ak_nz
Link to comment
  • 1 year later...
how does a deployed labview application have it's thread configuration set?  Do the changes you make in the threadconfig.vi somehow get put into the application ini that the run-time engine reads?

 

John

 

The configuration is contained in the *.ini file for the built application along with other properties such as vi server configuration. Here's an example of the content that updates the Other1 and Other2 execution systems maximum thread count for each priority. You can generate this programmatically as part of the application build spec with a Post-Built Action :

 

ESys.other1.Normal = 20
ESys.other1.High = 20
ESys.other1.VHigh = 20
ESys.other1.TCritical = 20
ESys.other2.Normal = 20
ESys.other2.High = 20
ESys.other2.VHigh = 20
ESys.other2.TCritical = 20

 

Note that you could also just use the same property settings in your LabVIEW.ini file for the same effect in the development environment. I believe this is all threadconfig.vi actually does however it doesn't touch any application build specs (not that sophisticated I'm afraid).

 

Here is a quick post build vi I cobbled together to generate the entries on every application build:

post-27534-0-01300200-1398971787_thumb.p

Edited by ak_nz
  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.