12-04-2024 05:29 AM
This is a copy of the final reply on this private conversation in 2021. It summarizes the work done on minimizing copying of large messages in Messenger Library. I'm copying it here so it is public:
Here's some notes. I'm quite happy with things, as I was able to get zero-copy for the "Event Notifications" in Messenger Library. I've been testing by passing 400Mb arrays from one Messenger-Library "actor" to another. This is much better than it used to be. What I had to do was:
A) my Message Objects hold data in Variants, and I needed to Swap in to the Variant to avoid a copy:
B) Because I usually just wire a non-variant to a Variant input, and that implicit conversion causes a copy, I wrote a VIM that puts in a To-Variant node, which doesn't do a copy:
C) The Notification system is written for arrays of addresses, as there can be multiple Observers of each Notification. Doing Send over an array in a For Loop leads to N copies. The get the N-1 copies (zero for one Observer) required looping over N-1 addresses, then doing the last address differently, like this:
D) To go through a User Event without two copies, I used DVRs, with the EventDVRMessenger described before. This requires a minor change to my DEV Message-Handling Template: just a Free-DVR node:
E) I had already been using Swap to get my Variants out of my Message Objects, but now I also use a new VIM that Swaps the data after conversion from a Variant.
By supplying an unbundle, from my main data-storing shift register, to the "Contents Data Type" input, this avoids the extra copy on the rebundle, as seen in this shot of the whole actor:
On the right is the initialization code to Launch a "Big Data Producer" actor, and to register for the Notifications holding the 400Mb arrays that Big Data produces.
On the left is the event case handling the Notifications (same case handle async replies, which i also tested to be zero-copy).
The time to Write, Send, Receive, and Read is less than 1ms for a 400Mb message. However, once one has processed a couple of messages, LabVIEW starts to free previous memory allocations, and apparently a 400Mb allocation takes about 45ms to free. From the Windows Task Manager, as well as DETT, i can see that three 400Mb allocations exist at any one time (I'm running 32-bit LabVIEW 2017).
12-05-2024 02:54 AM
Also found I had to prevent copies of an added array element by adding an empty element first then swapping in. Looks like this (done as a Malleable VI):
07-08-2026 04:07 PM - edited 07-08-2026 04:21 PM
Sorry to bring back this thread as I finally found a discussion about the swap value function used in your messenger library. Could you enlighten me a bit further in point A) how exactly the swap value function here would help performance? Does it only work for variant or it helps update class internal data as well? Thanks in advance.
07-09-2026 06:46 AM
Swap tells the compiler to swap, rather than what it often does, which is copy. Works on strings, arrays, variants. I would only use it while using the DETT to tell what you are doing.
07-10-2026 04:37 PM
Thanks a lot for the timely response. I also found your latest presentation about this topic. Really appreciate it. Have learnt a lot from your work!