Jump to content

Refactoring the ReferenceObject example in LV 8.2


Recommended Posts

When this is not the case you could use create a reference to the class using a "REF" operator.

Yeah right and get all the problems of C... No thanks. That's why you can't manually create a ref in Java. If you have an object (=ref) in Java then it is always poiting to an existing object (unless the reference is explicitely made NULL). Besides, in LV, what should the reference then point to, to an object in a shift register ? Which you can then silently modify without the "owner" knowing about it ? That's a can of worms.

Because in concurrent multithreading system like LabVIEW, using references requires concurrency control like semaphores to control the simultaneous access to the reference, the same performance cannot be gained than what can be gained with dataflow objects.

Well, don't we all have semaphores on our VIs that control parallel execution of the same VI ? We use this mechanism to make sure calls to functional globals (LV2 style globals) are serialized correctly and fairly. This shows it can be VERY efficient.

Joris

Link to comment

I could not agree more.

A general native way to use pointers/references in LabVIEW has been on my wish list from day one.

Especially now with LabVIEW RT and platforms like cRIO, a reference system would be great in order to minimize memory usage.

/J

Of course it could be. NI has implemented by-value classes that should be able to provide good performance when one doesn't need by-reference objects. These classes can take all the advantage of data flow programming optimizations (or at least they could). If one needs a by-reference classes, then instead of implementing all classes by-reference, I thinkt that a general by-reference system for both data and object buffers should be created. This way you could take advantage of by-value classes when they provide enough flexibility for your purposes. When this is not the case you could use create a reference to the class using a "REF" operator. Because in concurrent multithreading system like LabVIEW, using references requires concurrency control like semaphores to control the simultaneous access to the reference, the same performance cannot be gained than what can be gained with dataflow objects.

So I don't see any reason why NI should force developers to use by-reference objects if for a particular application better performing by-value objects are better. I rather think that there should be a way similar to C++ OOP to have both by-value objects and variables as well as by-reference objects and variables. So what I really hope is that NI will implement a general reference framework for all buffers, controls and constants no matter weather these are objects or normal variables.

Link to comment
Yeah right and get all the problems of C... No thanks. That's why you can't manually create a ref in Java. If you have an object (=ref) in Java then it is always poiting to an existing object (unless the reference is explicitely made NULL). Besides, in LV, what should the reference then point to, to an object in a shift register ? Which you can then silently modify without the "owner" knowing about it ? That's a can of worms.

Well, don't we all have semaphores on our VIs that control parallel execution of the same VI ? We use this mechanism to make sure calls to functional globals (LV2 style globals) are serialized correctly and fairly. This shows it can be VERY efficient.

You really misunderstood me. I really meant that the developers should be able to choose between by-value and by-ref object-by-object. Everything should really happen under the hood of LabVIEW so that the developer doesn't see all the nasty things of C. Uninitialized references should never exist. That also means that one should not be able to use uninitialized shiftregisters or uninitialized controls with registers.

Concurrency control can never be made 100% automatic. Software transactional memory (STM) is as close to automatic concurrency control as one can get, but even STM cannot handle concurrency control when you are doing I/O that cannot be "undone". When there is interactions between the software and the disk, network or hardware then developer needs to use some sort of locking system; i.e. semaphores are accesses at least under-the-hood of LabVIEW.

Link to comment
Yeah right and get all the problems of C... No thanks. That's why you can't manually create a ref in Java. If you have an object (=ref) in Java then it is always poiting to an existing object (unless the reference is explicitely made NULL). Besides, in LV, what should the reference then point to, to an object in a shift register ? Which you can then silently modify without the "owner" knowing about it ? That's a can of worms.

Well, don't we all have semaphores on our VIs that control parallel execution of the same VI ? We use this mechanism to make sure calls to functional globals (LV2 style globals) are serialized correctly and fairly. This shows it can be VERY efficient.

Joris

Take a look at this :D Is this the can of worms you are *pointing* to ? :D

Well, thanks to JFM there is at least some error checking in there while still being very efficient (twice the speed of queues). I have another one too, made in LVOOP and using Variants. That one is very general, but the more general it becomes, the less the efficiency is, and then you end up with a just as good alternative in an asynchrounous queue system. But it would be fun to compare the speeds of those two.

Link to comment
Take a look at this :D Is this the can of worms you are *pointing* to ? :D

No I was talking of a future native implementation by NI. The reference they would introduce, to what exactly would it point ?

If it were to point to data in a shift register, then that data should be able to become altered without the VI that contains the shift register knows it. That means you would throw the encapsulation of a functional global out of the window. Bad...

Link to comment
  • 3 months later...

I thought of an alternative for the community implementing the by-reference classes in LabVIEW. The idea is as follows.

One can create a dual hierarchy to any by-value class hierarchy. The dual hierarchy is identical to the source by-value hierarchy in a sense that it has a dual version of every class in the by-value hierarchy. In addition it would have a dual for every method in the by-reference classes. The connector pane of the dual methods would differ from the source methods in that all class terminals would be replaced with the dual counterparts.

As the private data member of the root class of the dual hierarchy one would have a single element queue reference of a LabVIEW object queue. The root class would have protected methods: Preview Object, Get Object and Set Object. These methods would give all the methods of the dual hierarchy an access to the object stored in the queue.

The dual classes would use these methods to store and access an object of the by-value counterpart of the class. The methods of the dual classes (dual methods) would be implemented so that they get the by-value object couterpart from the queue using Get Object method, cast the returned by-value object to more specific, then call the by-value method counterpart and finally use Set Object to store the by-value object back to the queue.

This sounds like a lot of work. However, principally one could write an automatic tool that would create the by-reference hierarchy for any by-value class hierarchy and update the hierarchy when ever the by-value hierarchy is changed. This way your actual classes wouldn't be contamined with the ugly by-ref stuff but you would still be able to use your classes in by-ref fashion. In addition you would have the alternative to use your classes in by-value fashion.

Anybody interested in writing such a by-value class to by-reference class tool that would automatically generate a dual by-reference hierarchy for any by-value class hierarchy? If the tool would still keep the dual hierarchy up-to-date when ever the source hierarchy is modified, then the actual implementation of the by-reference classes would be totally hidden from the user.

There are some problems I can see in this implementation. Dynamic VIs of the the source hierarchy should have Dynamic VI counterpart in the dual hierarchy where the dynamic input terminals should be replaced with the dual counterpart. This is obvious but the problem is what to do with class terminals in the source hierarchy methods that are not dynamic dispatch terminals. Or class terminals that are of an ancestor class type? Or class terminals that are not of any class type from the hierarchy being processed? Or terminals in wich a class type is in a cluster, an array, a queue or event reference or a combination thereof. I do not have an definite answer to this question.

Link to comment

As a few VIs tell more than a thousand words, I wrote a simple example of what I mean. Unzip the example and open the project. In examples folder there is a single example that represents the idea somehow. This is all very preliminary.

All by-value classes should inherit from the "Value Class" and all by-reference classes should inherit from "Reference Class". There are two hierarcies. The by-value hierarchy is the one that the developer creates manually. This example hierarchy contains a File class as a parent class and TextFile class as a child class. The corresponding dual reference classes are File Reference and Text File Reference. The dual hierarchy should be made automatically by some scripting tool. As I don't have such tool yet, I wired it manually.

Download File:post-4014-1169480015.zip

Link to comment
  • 1 month later...
  • 1 month later...

QUOTE(Jim Kring @ Aug 19 2006, 08:09 PM)

One of the problem I met when I work with this pattern is I can only get the variable of the object one time. In the meaning of an object, it's wrong here. I think we should be able to get the value of variable whenever we want without update these value.

I am still learning, so maybe I say wrong. Please don't mind give me recommendation.

Thank you,

Thang Nguyen

Link to comment

QUOTE(Thang Nguyen @ Apr 20 2007, 12:14 PM)

One of the problem I met when I work with this pattern is I can only get the variable of the object one time. In the meaning of an object, it's wrong here. I think we should be able to get the value of variable whenever we want without update these value.

If a process is going to do a "read modify write" then it needs to block other "read modify write" operatoins during the time it is doing the modification. Which means that a read has to block other reads. Although technically a "read modify write" doesn't have to block others that are just doing a read, it is a very rare application that needs that kind of functionality. A bank might have an object for a user's account. The bank might be doing a "read current balance, add some charges, write the balance back." During this time, should the customer be able to read the balance at an ATM? If the modifications are reasonably fast (and "reasonably" varies from process to process) then there's no real problem of the read-only process waiting on the read-modify-write process. Now, the objection can be raised that a read-only shouldn't halt all other processes. If a reader is going to take a long time before putting the value back, then it should read the value and make its own copy, freeing up the object for other processes to continue using. Here's the tradeoff : Either the read process is fine if other threads proceed with modifying the value, in which case having made its own copy is important so that it isn't sharing some pointer to a value with other processes that may be changing that value. OR the read process is not ok with others modifying the value, thus locking the value is appropriate.

Trying to create a scenario in which multiple readers share a pointer and yet all readers halt when ever that shared pointer is updated by a writer is a nightmare in any system and one that really isn't worth supporting most of the time.

Link to comment

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.