Jump to content

Critical Analysis and Alternative Implementation of Object Oriented Programming in LV 8.20


Recommended Posts

While trying out the LabVOOP, I searched the LabVIEW help and discovered that this implementation uses flatten data as storage instead of native data format. This could mean that to access only one attribute, LabVIEW still have to unflatten the complete structure?

My guess is that this is something that will change in time, because it makes no sense for NI to use flatten data when they have full control of the data handling. Anyway, I think that this is something that should be mentioned in the Critical analysis...

/J

I don't understand your question. What exactly is the difference between "flatten data" and whatever it is you think NI has access to? I'm not trying to be difficult, but I'm not sure what optimization you see.

"This could mean that to access only one attribute, LabVIEW still have to unflatten the complete structure?" When LV unflattens a string of data, it knows the type of the data because you wire a type descriptor to the input of Unflatten From String. With LV Classes if you wire a type descriptor of Parent, the data could be of type Child. This is perfectly legitimate. If, however, Child.lvclass is not in memory, then how can LV unflatten it? LV has no idea what Child.lvclass looks like -- its a data type that a user created. In fact, there may be many Child.lvcass files on disk. Which one did you intend? So, yes, we have to have the definition of the structure in order to access any element of that structure.

That's why I'm confused about post. I'm happy to address the point (and maybe update the Design Decisions document) but I'm not sure what needs addressing.

Dataflow OOP has however raised a need for totally new kind of reentrancy,

Actually, it suggests the need for about a bijillion different flavors of reentrancy. Or at least a consistent view of what "reentrancy" means. ;-) And that is part of why it isn't in this release -- it turned into a deep deep pit of issues, options and conflicting use cases.

Wire level reentrancy poses some serious problems. Let's take the issue of Custom Probes -- just to pick one. If the data goes down the wire, do you want a copy of your data going into the Probe (because it is going to be there after the execution continues past the probe) to be allocating new data spaces? There's some serious negatives for performance if you do, and some serious impact possible on the actual functionality of your VI if you do (because then running a custom probe would modify data).

Another issue: Should the reentrant dataspaces remain in controls after the VI finishes running? That would mean that as long as there's data of the class, you couldn't edit any of the reentrant VIs. That would be a serious problem. Or do we need to save off the current run state of every member VI for every class instance every time a VI goes idle and then restore that running state (uninitialzied shift registers and all) when you hit the run button or use Value property to get that value into another running VI?

Wire level reentrancy gets very icky very quickly. I don't like dumping on this idea, but it really is nearly unworkable. Once I really sat down and asked "what would it mean to have a VI dataspace associated with each object?", I ended up with many conflicting cases, which lead to unpredictable behavior. I think that wire level reentrancy is a fun idea that isn't really needed: if an object needs to store all of its data in itself, not storing it in local variables and uninitialized shift registers of member VIs, then it can initialze any shift registers that need to be "per object" whenever that method executes.

Something needs to be done to support reentrancy with classes. No doubt about that. But I don't think that wire level is going to work.

Link to post

Aristos,

I thought flatten data was a way to store arbitrary complex structures in a continous piece of memory, but it is not the way that data is stored in memory when that complex structure is passed in a wire?

Many flavours of GOOP floating around, uses some kind of flatten data as storage, and each flatten/unflatten operation requires memory allocation and copying?

So if NI could make LabVOOP work with the native datatypes instead of flattening data we would not see these memory allocations, with increased access speed and less memory footprint as the result.

/J

I don't understand your question. What exactly is the difference between "flatten data" and whatever it is you think NI has access to? I'm not trying to be difficult, but I'm not sure what optimization you see.

Link to post
Aristos,

I thought flatten data was a way to store arbitrary complex structures in a continous piece of memory, but it is not the way that data is stored in memory when that complex structure is passed in a wire?

Many flavours of GOOP floating around, uses some kind of flatten data as storage, and each flatten/unflatten operation requires memory allocation and copying?

So if NI could make LabVOOP work with the native datatypes instead of flattening data we would not see these memory allocations, with increased access speed and less memory footprint as the result.

AH! I found the miscommunication!

"Stores" in this case means "saves on disk or transmits across TCP/IP or explicitly requested by LV's Flatten to String prim".

In memory the structure is just as unflat as any other LV structure.

Link to post
  • 5 weeks later...

Wire level reentrancy is nice but can only be practically implemented with referencing wires (unlike the current implementation). Otherwise you would need to clone all method dataspaces when the wire branches. Not to mention visible frontpanels...

It would have been a fantastic feature.

Joris

Link to post
Wire level reentrancy is nice but can only be practically implemented with referencing wires (unlike the current implementation). Otherwise you would need to clone all method dataspaces when the wire branches. Not to mention visible frontpanels...

You would need to clone method dataspases when wire branches, but you can do it lazyly by cloning only those method dataspaces that are going to be used. Then LV should also have stateless VIs which wouldn't have a state, you should use these when ever you don't need a front panel or uninitialized shift registers. This way you can avoid dataspace copies when they are not really needed. LV now copies buffers when wire branches. Why couldn't ir also make a copy of a few dataspaces. After all most class methods don't really need state so in this paradigm they would be stateless.

Link to post
You would need to clone method dataspases when wire branches, but you can do it lazyly by cloning only those method dataspaces that are going to be used. Then LV should also have stateless VIs which wouldn't have a state, you should use these when ever you don't need a front panel or uninitialized shift registers. This way you can avoid dataspace copies when they are not really needed. LV now copies buffers when wire branches. Why couldn't ir also make a copy of a few dataspaces. After all most class methods don't really need state so in this paradigm they would be stateless.

I think you're cutting a corner here. There is (AFAIK) one stateless VI type now, the subroutine. All others have at least some state, even reentrant VIs, and this state data has probably become more for methods. A VI that has no "used" frontpanel objects and no shift registers is almost stateless already, so why introduce a new type ? I am in favor of storing the VI state with objects, also for front panels. That is ideal for drivers. But it is useless to store VI states with objects if objects are cloned without you notice it, like they currently are. Really, make some examples for yourself and you will be convinced. It's only interesting if the object wire would behave like a native reference.

Joris

Link to post
Because of the high performance gain the can be achieved and the ability to make recursive calls. Take a look at my entry at wish list.

If you have wire level reentrancy you usually would not need recursion. You could then call methods of other objects which is usually what you want recursion for: traversing a tree etcetera. You only cannot revisit the current object.

Joris

Link to post

Join the conversation

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

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