06-15-2005 09:04 AM
06-15-2005 09:33 AM
@enrico Segre wrote:
>but why not simply allocate the memory for the framegrabber by using LabVIEW's initialize array primitive? Then, when the data is returned, simply index into the array to find the data of interest.
ah, and besides: I want to allocate once the buffer(s) and to write there at video speed. Not to reallocate and initialize them at every call of the grabbing routine. This is what my "working solution" does currently, using some 10 ms on a fast PC (profile). Given that a new video field is available every 20 ms, and that I'd like to use cpu for online image processing, I'm trying to squeeze.
Enrico
06-15-2005 10:22 AM
06-18-2005 01:07 PM
06-19-2005 05:42 PM - edited 06-19-2005 05:42 PM
Message Edited by rolfk on 06-19-2005 05:49 PM
06-20-2005 07:16 AM
@rolfk wrote:
I don't think that this would work for the OP. First of all the pointer you pass in CreateBuffer to the DLL is only valid as long as the array wire is valid and not branched anywhere at all. Basically the pointer is deallocated (in fact reused here) at the moment the Array Subset function is executed and definitely deallocated in the terminal.
Also reused does not necessarily mean that the pointer does not change, as LabVIEW might decide to actually resize the handle in Array Subset and this could theoretically cause the array to be reallocated resulting in a different pointer value. While for this specific case it is unlikely that this is done, you would be relying on a specific behaviour, which can change with any new LabVIEW version for a number of reasons.
Another issue is that the capture library will likely fill the buffer at some asynchronous time and you need to add additional protection to avoid letting LabVIEW work on the array while the grabber tries to update the buffer content.
06-20-2005 04:57 PM
@Jason S wrote:
Actually, the buffer passed to CreateBuffer isn't used at all. It is the copy that is created inside the call that is used.
Secondly, simply branching an array does not cause any buffer manipulation to happen. One of the branches must be modified (say with a replace array subset element). Then, the buffer will be copied, not deallocated.
Again, I disagree. The Array Subset function allocates a new buffer, yes.
06-20-2005 04:58 PM
However, LabVIEW cannot deallocate the original buffer because it doesn't know what will be done with it on future iterations. As far as LabVIEW is concerned, the original buffer is allocated (in the DLL call) and continuously read (in the loop), but never modified. Since it is in continual use it cannot be deallocated. Since it is not resized, it will not be moved.
Because it is ultimately a handle, it is possible that LabVIEW could move the entire buffer for reasons other than resizing it. However, the only reason I can come up with to do that is some sort of "memory defragmentation" operation in order to clear up a sufficiently large block of memory. As this would generally be a terrible inefficiency, however, I doubt that LabVIEW does this.
06-20-2005 09:09 PM
@rolfk wrote:No data buffer is created inside the DLL call at all...
I must sheepishly admit that I did not check the buffer allocations on the final version of the VI. In a previous version, a buffer was allocated by LabVIEW on the DLL node, and that is the allocation to which I was refering. I'm not sure what the difference between this version and the previous was that caused LabVIEW to decide it didn't need to copy the buffer before sending it off to the DLL.The same array just having been resized to a smaller size is again reused in the next loop iteration with its original size as the wire coming in from the left. ... At least the Array Subset function would create an extra copy of the data.
You're correct about the optimization of the Array Subset, except for in one critical detail. In terms of actual memory, the array is not resized at Array Subset. If LabVIEW were to resize it here, it would risk having the rest of the buffer wiped out be some other unrelated memory call. It can't do that because it's going to need the entire original array at the beginning of the next iteration of the loop. That is the critical part of the entire example. Because the unmodified array (unmodified as far as LabVIEW knows, that is) must be available at the beginning of every iteration of the loop, it will not be disturbed. If it were moved, LabVIEW would have to copy it in its entirity, which would be an unnecessary waste of time in every instance I can imagine.
@rolfk wrote:
Another way you might possibly try to get the handle to survive in a loop through multiple iterations would be to wire it into a shift register.
Still this is not something you could rely upon as LabVIEW is still free to decide that it will rather reuse the handle in the Array Subset function instead of in the shift register...
See previous statements about same data be necessary at beginning of loop, thereby good optimization ensuring that it is the modified buffer, not the "unmodified" buffer that gets moved.
I guess I was also implicitly assuming that Enrico was just reading the data, and not modifying it in any way, in which case there are no worries at all. Well, a lot fewer. He seems to have lost interest in our little discussion, anyway. Sigh.Your example works since LabVIEW does some remarkable optimizations in a way which happen to benefit your particular setup. But for more complex diagrams it would be very hard to guarantee this same behaviour and you would end up with a situation where it either does not avoid the additional copy of the data in the Array Subset function or renders the buffer at latest in the Array Subset function useless for the DLL.
My example works because I rely on LabVIEW not to move what it thinks is an unmodified buffer while it is still in use. LabVIEW does have some impressive optimizations, but that's hardly one of them. The buffer copy, or lack thereof, in the Array Subset is irrelevent.
If you can prove me wrong, please do so. Please edit my VI, or create an equivelent that breaks. The critical things that must not change are:
- The wire that is passed out of the CreateBuffer function must be wired to the "data acquisition" loop directly and with no branches.
- This same wire must be accessed, in some fashion, to read or manipulate the data.
I assert that any manipulation of the data inside the loop will leave the original buffer unmoved. It will certainly work everytime in the current version of LabVIEW. I believe that it will work as far back as 5.0 (that's as far as my experience goes), and I am confident that it will continue to work in the future, though I wouldn't sell an application that relied on it.
I'm not trying to be rude or unduly challenging. I just think that my method will work, and for my own benefit and those who read this forum, would be interested to know if I'm wrong.
06-21-2005 01:15 AM
I must sheepishly admit that I did not check the buffer allocations on the final version of the VI. In a previous version, a buffer was allocated by LabVIEW on the DLL node, and that is the allocation to which I was refering. I'm not sure what the difference between this version and the previous was that caused LabVIEW to decide it didn't need to copy the buffer before sending it off to the DLL.
You're correct about the optimization of the Array Subset, except for in one critical detail. In terms of actual memory, the array is not resized at Array Subset. If LabVIEW were to resize it here, it would risk having the rest of the buffer wiped out be some other unrelated memory call. It can't do that because it's going to need the entire original array at the beginning of the next iteration of the loop. That is the critical part of the entire example. Because the unmodified array (unmodified as far as LabVIEW knows, that is) must be available at the beginning of every iteration of the loop, it will not be disturbed. If it were moved, LabVIEW would have to copy it in its entirity, which would be an unnecessary waste of time in every instance I can imagine.
My example works because I rely on LabVIEW not to move what it thinks is an unmodified buffer while it is still in use. LabVIEW does have some impressive optimizations, but that's hardly one of them. The buffer copy, or lack thereof, in the Array Subset is irrelevent.
- The wire that is passed out of the CreateBuffer function must be wired to the "data acquisition" loop directly and with no branches.
- This same wire must be accessed, in some fashion, to read or manipulate the data.
I assert that any manipulation of the data inside the loop will leave the original buffer unmoved. It will certainly work everytime in the current version of LabVIEW. I believe that it will work as far back as 5.0 (that's as far as my experience goes), and I am confident that it will continue to work in the future, though I wouldn't sell an application that relied on it.
I'm not trying to be rude or unduly challenging. I just think that my method will work, and for my own benefit and those who read this forum, would be interested to know if I'm wrong.