I have been trying to get the following information into the public domain for years and now that I have the answers, I will share with those that may be interested.
Wrap your head in duct tape before reading just for safety sakes.
My two questions have been;
1) can LV Re-use the buffers of the calling VI when using VI Serve Call by reference?
2) Is the UI thread used when using Call by reference?
1. When calling a VI using the call by reference node, does the data going into the connector pane of the node get copied, or is it in-line as it would be with a properly set up subVI?
Short answer: It is somewhere in-between.
The compiler doesn't know what VI will be called, but it does have a hint:
the reference wired into the Call By Reference node. It uses that to get the "Prototype" for the call. So for the best performance, use a prototype that has the same "in-placeness characteristics" as the called VI. That being said, users don't know what the "in-placeness characteristics" are.
Before I go into the details, I should say that the overhead of these copies shouldn't matter much unless it is a large data structure (an array with a lot of elements, or a cluster/class with many fields or containing large arrays etc.).
If the prototype does not modify the data then the compiler assumes that the Call By Reference node will not modify the data. However at run-time a check is made to see if the actual called VI will modify the data. If so, then a copy is made and passed in so that the original data can remain unmodified.
If the prototype contains an input that is wired through to an output in such a way that both the input and output terminals can use the same memory buffer, but at run-time a check determines that the actual called VI's input and output do not share a buffer, then a copy will be made from the actual call's output to the original VIs (combined input and output) buffer.
I should also mention that even with this "attempt to agree with the prototype" behavior, it's not always possible to get as good performance as a regular SubVI call. For instance if you have a situation where the prototype does not modify the data and passes it through to an output then the compiler must assume that the data is modified (because as in example 2, there exist VIs that may modify it even if the actual VI called does not).
And there are some caveats:
1) This "using a prototype" behavior was new to 2009. Before that we used a more naive way of passing data that assumed all inputs will be modified and no outputs share a buffer with an input.
2) This behavior is subject to change in future versions, if we find further optimizations.
3) This behavior is the same as we use for dynamic dispatch VIs (when using LV classes)
4) If you want to create a VI only to be used as a prototype, then you can use features of the In-Place Element Structure to control the "in-placeness characteristics" Namely the In/Out Element border nodes, the "Mark as modifier" feature of the border nodes (note the pencil icon on the In Element), and the Always Copy node.
5) The prototype is only the first reference ever wired into the Call By Reference node. So if you do make a new prototype VI, you can't just make a reference out of it to wire to the Call By Reference node. I suggest deleting the Call By Reference node and dropping a new one.
6) For remote calls, we always have to "make copies" by passing data over a network.
I hope this helps, if you want any further information/clarification, then feel free to ask.
2. Does the call by reference node execute in the UI thread? If the call is being made by a remote machine over ethernet, which thread does the host (the machine that makes the call by reference) execute on and which thread does the target (the machine that contains the VI file) execute on?
In the local case, the Call by Reference node does not require the UI thread and can run in whatever thread the VI wants to execute in.
When calling a remote VI, the Call by Reference node uses the UI thread (detailed below) on both the client and on the server.
The client uses the UI thread to send the call request to the server and then again when the response comes back. The UI thread is not blocked during the time in between.
The server receives the TCP message in the UI thread and then starts the call in the UI thread. The server also uses the UI thread to send the response back to the client. The UI thread is not blocked on the server during the execution of the VI.
I hope people find this when they need it!
Solved! Go to Solution.
I gave you one.
How do I get the duct tape off now?
Just pull really fast so it doesn't hurt so much.
I will leave my Duct Tape on until the pressure subsides.
Based on my experience, unless it is placed on a duct, duct tape is fairly permanent. My advice is to learn to live with it, and every so often add a new wrap for aesthetic purposes.
I just had somebody knocking on my cubicle wall this morning asking just this question.
I'd give you a Kudoes if i could...
I suggest hanging a sign indicating "No Caffine Zone" on the cube enterance. This would tend to prevent the asking of questions that have duct-tape mandatory answers.
Thanks for the details though! (duct tape off.....ouch!)