Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    204

Posts posted by Aristos Queue

  1. OK, you've convinced me. I'll move it out of the subVI. It seemed to make sense in my situation, but I can see where it could lead to problems.
    I've seen it in cases where the subVI itself was named "Close", but there was some other work to be done along the way. It should actually be common when using DVRs with classes since the only way you *can* close the reference is in a subVI if the class options are set to restrict it (which they are by default).
    • Like 1
  2. And on that note, am I the only one who finds debugging/tracing in LabView more useless than useful - with each VI opening two windows until you're completely lost. Any plans on somehow making the experience better?

    It's been that way for 25+ years. I doubt that anything substantially altering that situation is likely anytime soon. I actually find the experience fairly straightforward when I compare it to 4000 lines in a .cpp file that I'm scrolling up and down through. Even in C# where files tend to be on the order of 100 lines, the windowing situation gets pretty bad. At least with LV you can observe from the probes behavior at deep levels of the program instead of having to actually be watching those levels real time to see watch window results.
    Yes, I have identified a deadlock as well. Unfortunately it was wrapped into multiple layers of VIs, so it wasn't obvious at first and required two days of tracing to discover.
    That, by the way, is the number one reason to not use data value references. Yes, they're bright and shiny and new in LV 2009 and a bijillion users have thanked us for adding them to the language, but I continue to argue that the vast majority of the time the same work can be achieved with dataflow and doing so would avoid the deadlocks and race conditions that too often crop up. Yes, there are rare situations where you really do need a DVR, but its way less common than most people seem to believe. Perhaps having spent two days searching for the deadlock, you'll now spend a couple days thinking about whether it is possible to architect your code without any DVRs to avoid this in the future. I'm not saying it is necessarily possible in your case, but I believe it is worth thinking about.
  3. When working on a project I use the project explorer window to drag and drop vis onto the bd I'm working on. If the project is large it can take a lot of scrolling and clicking to get to the VI I need. Has anyone ever implemented a project-specific palette?

    I'm not sure I understand the goal. Given that you (like myself) use the project as a palette, what would you put in this project-specific palette? If it is anything autogenerated, wouldn't it just be the project, and thus would get as large as the project window already is?
  4. Those of you making August plans for NI Week may be interested to know that the light rail commuter line actually opened this week in Austin, and one of the train stops is next to the Convention Center where NI Week is held. That may open up possibilities for visiting sections of Austin that you haven't explored in previous years without renting a car. Unfortunately, the line doesn't run out to the airport, so you'll still need a shuttle to get downtown in the first place.

  5. I do not know much about SciWare's GOOP, but any refnum or resource (like a task) that is created in LabVIEW is automatically disposed when the *top-level* VI that created it goes idle. Is it possible that you are creating the DAQ task in some VI that is being called using the Run VI method of VI Server, and that VI is going idle and thus throwing out the newly created task?

  6. Or a typedef with a large default value? I don't think I would have one, but I could envision someone creating this data as default to avoid having to allocate it explicitly.

    No. A terminal whose type is a typedef does not get the typedef's default value as its default value. So if you have a typedef of an Int32 whose default value is 5 and you put that inside a For Loop and tell it to execute zero times, the value you'll get out is 0, not 5. Typedefs define a type, but they do not define all the behaviors of that type. The default value set on the FP of the control editor is just the default value of any controls of the typedef. If you need a type where the default value is actually defined as part of the type, you need a LabVIEW class.

    Although, and I right in presuming that if one were using an object instead of a regular cluster, even if the defaults were large strings / arrays, the additional memory allocation would only be 1 pointer-sized int?

    Yes. And that one pointer would point back to the master copy of the class' default value.

  7. Thanks for you offer and help but I need to "write" the the code to my graduation work.
    WOO HOO! Dear chcastro: You have no idea how happy it makes some of us on this board to hear a student who actually *wants* to do his/her own homework. We get a lot of requests asking for someone to write assignments for students.
  8. If you use a Diagram Disable structure for this, it makes your intent clearer. You can also use 'create constant' but you will want to make sure that it doesn't have some non-null value in the constant when you create it.

    Please don't do this. The fact that LabVIEW allows "Use Default If Unwired" on conditional disable structures continues to cause all sorts of problems, problems of such complexity that various people are pushing to mutate that feature away in future versions. A block diagram constant of a reference type is ALWAYS "not a refnum". Just use that.

    If you're interested in the kinds of problems, here's just one for a sample: You have a disabled diagram structure with three frames, as shown below:

    post-5877-12693834114_thumb.png

    You save the VI and close it. Later, you load this VI back into memory, but this time, someone has edited the subVI to have a different output type. When LV checks the types of terminals of this diagram, this time it decides that the output type needs to be the new type, which causes your diagram to break. That's a problem since the whole point of diag disable is supposed to isolate your code from the possibly broken code inside the structure. Similarly, if the subVI is missing, LabVIEW will use the third case to determine the tunnel's type, and the output would turn to double instead of string.

    This is one of the easy cases. They get much more bizzare and it is all the fault of "Use Default If Unwired".

    • Like 1
  9. Does that mean that there's a new buffer allocation?
    I went and asked. Here's the details:

    The Read Reference node of the IPE always has a buffer allocation standing by in case the data value reference coming in is invalid. So the code inside the structure is pointed either at the data brought in by the reference or the local allocation. The local allocation is initialized with the type's default value whenever it is needed. If we did an on-the-fly allocation, we'd have two problems: data allocations in RT (where, believe it or not, DVRs are actually safe to use as long as you guarantee there's no contention for them, so you can use them for the "guarantee no data copies use case") and complex logic for tracking when to deallocate an on-the-fly allocation.

    Top-level data size for the default value is generally small, so it really isn't worth worrying about most of the time -- you'd have to have a giant cluster of many many doubles to get significant top-level data size.

  10. I find this statement however implies behavior I'd not expect from LabVIEW...are you implying that in this case, if auto handling is enabled and you have an unwired error terminal on an IPE node whose mated side *is* wired, LV won't automagically halt execution when an error is generated? Does this apply for variants as well as DVR nodes?

    Variants? I have no idea what you're talking about. But, yes, you have the behavior correct. Those two error terminals are the same error, just available at two different locations on the node -- where "node" in this case means the combined pair of the DVR read and DVR write.
  11. To add to DJed's post:

    In the particular example posted, you don't need the Merge Errors.vi at all because there's no reason to merge a guaranteed "no error" with the other error stream.

    Also, technically the write/unlock node does nothing but release the DVR's lock and thus cannot return any new error.
    Or, to phrase it another way: BOTH "ERROR OUT" TERMINALS RETURN THE SAME VALUE. So you never have to merge these two error streams. Automatic error handling is satisfied if you wire either one of these two error terminals.
    • Like 1
  12. Thats interesting I thought NI would recommend re-entrancy and use it too! :wacko:

    Yeah... I thought that too until our Chief Architect came to have a talk at my desk after I converted one batch of VIs to reentrant and caused LV's Getting Started Window to quintuple its memory allocation.

    Normal reentrancy solves concurrency issues at the cost of memory allocation. The vast majority of subVIs are never under parallel contention, so making those subVIs reentrant simply increases memory usage, which generally means a performance slowdown because things start paging in and out of memory, take longer to load from disk, and generally aren't cached because all the parallel copies keep knocking each other out of the caches. Only when you have parallel contention do you get a performance gain from use of normal reentrancy.

    Shared reentrancy is a different beast. Only one clone is in memory. If two subVI calls to that clone try to happen at the same time, a second clone is allocated. Once allocated, that clone stays allocated (I think as long as the VI stays in memory without being edited, but it might only be as long as the VI stays running... I'm not sure which). What this means is that you take a performance hit when that second clone gets allocated, but thereafter you get most of the benefits of parallel execution. There's slight thread friction each time the caller VI accesses the clone pool at the start of the subVI call, but that's minimal compared to the friction of being entirely serialized. Shared reentrancy appears in empiric tests to be a good compromise.

    There's a new feature on the horizon that will introduce yet another variant to consider, but you'll have to wait to August to hear about it (unless you join the beta program and help LV by doing a bit of testing in exchange for early enlightenment).

  13. If it works for VIs generally, then you should keep the same policy for methods of the class. Classes are just a system for organizing the VIs you'd write anyway. And being reentrant does mean all overrides have to be reentrant, but that shouldn't be a problem. For one thing, method overrides are generally adjustments to the parent's behavior, so if the parent didn't need synchronization, neither will the override. And if it really needs synchronization, the override can call a subVI.

    • Like 1
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.