- Popular Post
-
Posts
3,183 -
Joined
-
Last visited
-
Days Won
202
Content Type
Profiles
Forums
Downloads
Gallery
Posts posted by Aristos Queue
-
-
True... and I should probably set a better example for customers who are in Beta Club... but I get some special dispensation from time to time.The first rule about Beta-Club is you do not talk about Beta-Club! -
Naaah. He just means they've added more wizards
Yep. Lovely lovely wizards. :-)
-
And for many people, that fastest route is LVOOP (especially if I'm taking the exam with LV 2012... hehehe).Without getting off-topic too much here, don't you guy's think someone wanting to pass the CLD exam would want to take the fastest route to success? -
Regarding 1: I strongly disagree. That puts you right back to an enum which is what we are trying to eliminate . The current solution I posted has the message carry with it the instructions to perform so the set of actions possible is open ended.
-
Oh, man… The number of times I’ve double clicked on a subVI, double clicked on its icon to bring up the editor, made a copy, closed the editor, opened another VI’s editor, pasted. What a waste of time!
If the Icon Editor persisted the layer information to the clipboard when you copied, then it wouldn't necessarily be a waste of time, but that's never been implemented in any of the icon editor plugins that I've seen.
-
Here you go:
-
2
-
-
- Popular Post
If you want to see a Certified LabVIEW Developer sample exam written using LabVIEW classes, I am uploading one here. I built this over the last four hours in response to comments in another LAVA thread which correctly pointed out that a sample CLD written with classes was not available for review.
-
If you wish to comment on improving this class-based sample exam or ask questions about how it works, please post them here.
-
If you wish to debate whether LabVIEW classes are worth using or whether they are overkill for real apps (including for the CLD exam itself), or any other philosophy, please post in the original thread that spawned this.
The sample exam that I did was ATM version 2 (I am attaching the PDF to this post for ease of reference). After 4 hours, I have the solution posted below. It is not a fully fleshed out app -- it is exactly what I have finished after 4 hours and would have turned in on the exam. It is very similar to what I turned in for my actual exam, although I will note that for my actual CLD, I specifically brushed up on file handling and had that working. Tonight, I was unable to recall my cramming, so that just got dropped (but documented as a TODO!).
Top level VI is ATM UI.lvclass:Main.vi. This VI takes an ATM UI object as input in case configuration options are added to this application in the future -- those options are already part of the UI loop.
Issues that I know of:
- File I/O is not done, as I mentioned above.
- The display strings are placeholders ... I didn't type out all the proper strings.
- There's no way for the user's name to be displayed when they put in their card.
- Although I documented the VIs, I did not fill in documentation into the classes themselves and probably should have.
Other than that, I think it all works given the limited testing I was able to do within the 4 hours.
I have no idea why I felt the need to make setting the display message go through an event instead of just setting the local variable every time. I think i had it in my head to bottleneck the localization, but that doesn't work, of course, because you have to be able to format information into the strings. That should probably be removed entirely.
I did build a message abstraction from ATM UI to ATM, but I didn't build a messaging abstraction from ATM to ATM UI. Why? Because I thought the data needed to respond was always the same. It wasn't until later that I decided that was a mistake, but I figured I should finish out this way. Building a true abstraction layer for completely isolating the ATM from the ATM UI is probably more than can be done in the 4 hour block unless you've got some scripting tools to back you up -- we'll have to see if it's reasonable in LV 2012 (without going into detail, assuming the beta testing goes well, there will be tools to help this exact problem in 2012).
-
4
-
Please define the term "dynamic VIs" ... are you talking "VIs that you load dynamically using Open VI Reference or the 'Call Setup' pop up menu option on a subVI node" or are you talking about "dynamic dispatch VIs that are members of LabVIEW classes"?
The answer to your questions will vary greatly depending upon which of these two technologies you're asking about.
-
Yeah, it kind of does, but I won't tell the Powers That Be if you don't...It's right on the Getting Started Window (new project from template, or so). See the beta forum for an update to the sample project, though. Arg, this doesn't count as talking about the beta, does it?
jbjorlie: Read the beta forum for comments from me about this.
-
The controller can also listen in on those same messages... as I said, there can be a bit of bleed over between the responsibilities of the view and the controller. Keeping them firmly separated is a goal needed by some applications but far fewer than the number of applications that need an absolute wall between the model and everything else.
I'm probably not describing this in helpful terms. I have an example of exactly this, but it isn't something I can post at the moment... if you join the LV 2012 beta program, the beta of 2012 went live today and there's a shipping example in there for exactly this with the AF.
-
This was not a known issue. I have filled CAR 337019. Do you know if it affects the Desktop Execution Trace Toolkit as well? (I told them to check both, but if you know off the top of your head, I'll add that to the CAR.)4) Also for the record, the RTETT traces do not show which dynamic dispatch VI is running (as of LabVIEW 2010). This hasn't been a big problem for us in practice. -
Daklu wrote:
> I wouldn't do this. It's giving the business components (motor controller, etc.)
> responsibility for deciding how the data is displayed.
Totally agree. This is the basis of the separation of
- "model" -- the hardware/business logic/process/software simulation/whatever you're actually doing
from
- "view" -- the UI layer or data logger system that records what's going on
from
- "controller" -- the section of code that decides what new instructions to send to the model
Model generally knows *nothing* about view or controller. Any view can connect to it. Any controller can send it orders. The model publishes a list of (events for the view to listen to OR messages sent from the model) and a list of (events for the controller to fire OR messages that can be sent to the model). The controller knows little or nothing about the view (binding these two is sometimes more acceptable). It publishes a list of events/methods for the view which tells the view what commands are available right now and lets the view command the controller.
-
1
- "model" -- the hardware/business logic/process/software simulation/whatever you're actually doing
-
This same change will have effect of removing a copy on control refnums and .NET refnums also, although the effect will be much much smaller since the maximum amount of data copied in those cases is a single int32.
-
Victory!
That output terminal will not be needed as of LV 2012. There was a (bug / unimplemented optimization -- depends upon your view) that made LV add a copy at certain upcast coercion dots. This compiler (fix / upgrade) will have performance benefits for a wide range of LVOOP applications. The change was implemented months ago, so this API doesn't get credit for finding the issue, but the compiler team verified your VIs do benefit from the change.
I would therefore recommend not putting it into the API as removing the terminal is a possible mutation issue, and not having the output terminal for a read-only operation is a much better API overall.
-
2
-
-
The online help that ships with LabVIEW discusses this topic. Take a look at that and see if that answers your questions.
-
That's my hometown. Spent 18 years there before going to university. Good place -- couldn't find a job there when I graduated, and my parents moved away, so I haven't been back in years. I'm glad to hear that someone's able to make a living in software there nowadays.I am in Tulsa, OKLAHOMA! (always add the ! after Oklahoma! for dramatic effect).
Thanks for the critique. I mean that -- the AF was designed to go after real world code, so hearing that there are real world scenarios it cannot handle is useful feedback.I love the idea of the AF and he must be quite a scientist to have created it. However, it seems on the verge of too much "safety" at the cost of usability, especially when introducing it into existing code. I hope the discussions there result in some small modifications to lower the entry barrier before it gets plopped into the <vi.lib> for eternity.Your point has had some discussion, both on the forums and elsewhere. My position at this point is that there's a difference between "for the newbie" and "for new projects". We've had a couple of newbie LV users pick up the AF just fine -- I'm not worried about its usability in that respect. The existing projects aspect is a different story. Plopping the AF into existing code frameworks was not a goal we had in mind when building it. I'm not adverse to adding features to it to make such adaptations easier, but not if they come at the cost of the provable correctness for apps built with AF from the ground up. Powell had a useful suggestion the other day for a new asynch reply class that might help... I don't think I'll put it in in time for LV 2012 (we're already *way* late in the dev cycle, what with the beta releasing already, and although there's still some window for feature adjustment based on that feedback, I try to reserve that coding window for "it really is unusable" sorts of adjustments), but I like the idea going forward.
Also, being in vi.lib does not prevent us from making adjustments, it just means those adjustments have more overhead if it requires mutating existing user code.
-
Hold off on finalizing this until the end of the week, please. I'm asking compiler folks to investigate the performance gain of adding the output terminal to see if there's another way to get that gain OR if it could at least be made unnecessary in LV 2012. Since this affects the conpane of the VIs, and that would be hard to remove in the future, it would be better to publish without it.
If you don't hear from me by the end of this week, ping me, please.
-
2
-
-
Catapult or walking. The carbon footprint of being fired out of a cannon was too high. :-)BTW, having never been to NI Week or an Architectural Summit, how do most people get from the airport to the hotel?
Seriously, though, the only answers I know of are rent a car, phone a friend or call a taxi.
-
My interest in OpenG is mostly as a "what is LV missing" point of view. For example, I have long coveted the OpenG array palette, wished that LV had those functions in vi.lib directly. Most of the OpenG palettes are better as add-on libraries, IMHO, but that one feels like core functionality, and I've certainly cobbled my own version of several of those functions. Some of the other OpenG tools/palettes I've seen over the years have highlighted places where you guys could have done an even better job if we had tweaked things a bit inside LV. If nothing else, they highlight the parts of LV that you guys are using the most, which are the areas we should probably be focusing on.
In the future, I may be more interested in OpenG as a user of the tools... I'm doing more G programming these days, and even a little bit on the side that isn't for NI projects. Just a smidge, but it's more than has been over the last decade.
Ah, that rules out the OpenG palettes, Darren, but not the OpenG tools, like some of their scripting accelerators.Most VIs I write ship as the source code of NI product features. It's my understanding that including open-source VIs in those features would not be allowed.
-
I will be at both summits. I am interested in OpenG.
-
1
-
-
There's a request on the Idea Exchange to make the index terminals on array index accessors Required instead of Recommended. It's an easy change for me to make, one I could even drop into LV 2012 (I still have access to the source code for that branch). But I don't know whether it's a good idea or not. There's comments in the page. Since IE only allows Kudos up, if you don't like the idea, post a comment explaining why. If you do, just kudos the idea. I'll make a call at the end of this week whether to make the change or not. It won't be in the first beta for 2012, but I can still hit release, I think (assuming I get permission to make the change... late game changes like this are iffy because they miss a round of user beta testing that might get some user to say "hey, that causes me problems").
-
Nope. There are other languages -- I have worked with both Haskell and Lisp, but there are others -- that are reference-free on existing operating systems.Too bad you weren't involved in the FileIO/driver design from the start, then LV might have been a pure data Flow language.But maybe we need to start with a Pure DataFlow operating system to get it working properly.
-
You wont get 1403 from a class not in memory problem. 1403 only occurs when you flatten an object of class XYZ to a string, then try to unflatten that string using a completely unrelated XYZ class -- like flattening an XYZ that contains an integer and then unflattening with an XYZ that contains a string, and not a different version of the class, but one where we try to interpret that integer as the length bytes of the string and realize we don't have enough bytes in the flattened string to represent a string of that size.
I don't know exactly what you're doing, but my first bet would be cross-linking of some sort. In other words, the class that you're using during development is *not* the same class that you're loading in your built application.
-
All very simple applications could be done in pure Data-Flow, but as soon as you use any advanced features such as: File-IO, DaqMX, Vision, Queues, Semaphores, DVRs, Instrument References you are using references.
Only because our hardware APIs are so poorly designed as to require references. The world doesn't have to work that way, but by historical precedent it does.
LV OOP Kd-Tree much slower than .Net, brute force
in Object-Oriented Programming
Posted
Hi, jkflying. Welcome to LabVIEW.
You've now heard the position of the "OO is bad" crowd. If you'd like to rewrite without classes, go for it, but that's not the bulk of your performance problem. If you're like 90% of the world's programmers, you'd probably prefer some help getting the OO solution up to speed. So let's look at what you've got.
There's a lot of text in this post, but I've tried to break it into short paragraphs -- each one is independent, so you can read each one and absorb it by itself without having to take in all of this in one go.
First of all, remove the Timed Loops from your test harnesses. Timed Loops have side effects on the thread scheduling and prioritization of LabVIEW. Lots of things that could be faster are not in order to get determinism within the timed loop (in other words, repeatable schedule is more important than fast schedule on any given iteration). I do not understand the details well enough to teach them to you -- it's an area of LV outside my normal baliwick -- but the long and short of it is that Timed Loops are meant to provide fixed scheduling for real-time deployments, and using them for other purposes will have undesirable side-effects. Instead of timed loops, you can use a Flat Sequence Structure, with a Get Date/Time In Seconds node in the first frame, your code in the second frame, and another Get Date/Time In Seconds node in the third frame.
Now, about the benchmark itself... any language has problems where it just cannot outcompete another given language, but I do not think we are dealing with one of those in your case. One major item to consider: is the .NET implementation thread safe? A lot of the overhead in your code implemented in LV is going into thread safety for that kd tree to be used in parallel branches simultaneously... I'm going to guess that the .NET code is not thread safe if only because almost nothing that C# programmers write is thread safe (haven't looked at your implementation). Unless the .NET solution is doing the same level of mutex locking, you're benchmark comparisons are skewed. We can get the LV implementation up to speed, but this is one of the common problems with comparisons between LV and other languages: as long as everything is dataflow, our compares match theirs. Once you introduce references, we implicitly buy the cost of thread safety, where as they leave you to implement that yourself if you decide you need it. What that often means is that small test apps used for benchmarks suffer because we've got overhead, but real world apps are faster because we then use that thread safety to achieve parallel performance. Please keep that in mind when evaluating.
Looking at your code... you use LabVIEW Object as the type of your DVRs, which is the reason you need all the To More Specific and Preserve Run-Time Class primitives. Introduce a parent class (kdtreeparent.lvclass) that has the methods on it that you need (dynamic dispatch). Have kdtree.lvclass inherit from it, and use kdtreeparent.lvclass inside the DVRs. Now when you access a DVR inside the Inplace Element (IPE) structures you avoid the fairly expensive dynamic type checking. The dynamic type checking is getting a speed boost in LV 2012, but it is better to remove it entirely.
Using the queues as stacks is fine... they're optimized for that use case. However, you should definitely not name the queue... you've got the name "Stack" wired in. That means that you're using the same queue as anyone else who uses the name "Stack". It's just like putting a variable in the global namespace. Bad things happen. There are legitimate reasons for using this feature -- ok, one legitimate reason -- but this isn't it.
Inside addExemplar.vi, you're using Read Left.vi, Read Right.vi and other accessors. Although it is normally fine practice to use your accessors inside the other methods of your class, in this case, I suggest using a plain Unbundle node (not the IPE) to access those fields. The reason is that you're extracting multiple fields and you'll be able to unbundle multiple at once.
Read Domain.vi, as written and used inside addExemplar.vi, is very expensive (and, side note to previous posters, it would also be expensive with plain clusters). You are calling Read Domain.vi and then wiring its output directly to an Index Array node. That's producing a duplicate of the array every time. Instead, create an accessor on Exemplar.lvclass that accesses the domain inside the IPE, indexes one element, and returns that out of the subVI. With that, you'll only be copying a single floating point number instead of allocating a whole array.
In the isTree.vi, you are doing the "!= infinity" check outside of the IPE. This is copying the floating point integer. You can avoid that by moving the "!= infinity" computation inside the IPE. Similar performance improvement can be done in other VIs in your hierarchy.
I am confused about why AddToTree is destroying the DVR and then creating a new one instead of just accessing the DVR through an IPE. If this is a trick to avoid initializing the class (which is my guess as to why you're doing that), you've just introduced a significant thread synchronization problem. If you fork your tree wire on the top-level VI, when you call Add on one branch, you'll invalidate the DVR refnum that is still inside the tree on the bottom branch. And now you'll get errors from that other branch, or just lose all your data. Probably not what you want. This should just access the DVR using an IPE and you should have a Create Tree.vi that returns the object populated with the top-level DVR and a matching Delete Tree.vi which knows how to traverse and deallocate the entitre tree and throw away the top-level DVR.
On that same note, you really should include this in your test cases:
That will show you a big problem with your current implementation. It is a bad idea to put the meta data about the contents of a DVR as by value fields of your top-level class (or cluster) and have the refnums shared. Putting the whole data block into a single top-level DVR makes this truly behave like a refnum type. What that means is that all of your public VIs will all start off by accessing a DVR in order to get access to all the fields that are currently in your kdtree.lvclass private data cluster. Oh... and change your wire color to refnum cyan (it's a predefined color in the color picker) to let people know that your wire contains (and therefore behaves like) a refnum.
Those are the big points. You didn't pick an easy problem for your first out-of-the-gate project. A basic KD tree is kids stuff... a thread safe KD tree? That takes a bit more to reason through. You've got a good start here, though. I have seen DVR-with-classes implementations for other data structures that can beat or exceed .NET thread-safe structures performance, so if you keep chipping at it, I'm confident you can get there.
Happy wiring!