JDP Science Tools

cancel
Showing results for 
Search instead for 
Did you mean: 

Notes on Memory optimization

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:

 

2021-10-11 16_22_11-SendMSG.lvlib_VariantMSG.lvclass_Write VariantMSG.vi Block Diagram on All Messan.png

 

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:

2021-10-11 16_22_45-SendMSG.lvlib_Write Message.vim Block Diagram on All Messanging Related.lvproj_M.png

 

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:

2021-10-11 17_02_41-Observer.lvlib_ObserverSet.lvclass_Send.vi Block Diagram on All Messanging Relat.png

 

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:

2021-10-11 16_24_33-Top Level Actor.lvclass_Actor.vi Block Diagram on All Messanging Related.lvproj_.png

 

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.  

2021-10-11 16_25_58-SendMSG.lvlib_Extract Message Contents.vim Block Diagram on All Messanging Relat.png

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:

2021-10-11 16_32_13-Top Level Actor.lvclass_Actor.vi Block Diagram on All Messanging Related.lvproj_.png

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).

0 Kudos
Message 1 of 2
(136 Views)

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):

drjdpowell_0-1733388836602.png

 

0 Kudos
Message 2 of 2
(114 Views)