Jump to content

mje

Members
  • Posts

    1,068
  • Joined

  • Last visited

  • Days Won

    48

Posts posted by mje

  1. I am actually concerned about a slightly more subtle issue. The use of subarrays means that the primitive is about as efficient as possible, no extra allocation is required. I am worried that LV will not recognize when it branches the wire and will create a copy, which it will not do for index array.

    Gotcha, my bad.

    It may be better in later versions with more compiler optimizations, but some quick testing in LV9 shows that Delete from Array is *much* slower than Index Array. What I do is create a large array and read the last element N times using Delete from Array and then using Index Array (with the necessary math). No array changes, I simply read the same element repeatedly. Delete takes roughly 1 sec for my test, Index takes about 1 msec.

    Eek! I really hope this isn't true anymore.

  2. I get a little twitch every time I branch an array wire, I have convinced myself that the compiler is clever enough to know that branching into an Index Array will not modify the array so inplaceness will survive. In most cases LV is also good at ignoring the code related to unwired outputs in the primitives, but I would be (pleasantly) surprised if the compiler recognized that branching an array into a Delete primitive to simply get the last element was also inplace.

    The help mentions subarray for both outputs. A very important distinction to many of the array primitives if you're worrying about memory. I think what LabVIEW really needs is a good discussion in the help about what a subarray actually is with proper links from the primitives that can actually create subarrays.

    For the uninitiated, subarrays don't require new allocations of the actual array data as long as you don't go modifying the data in either the subarray or original array wires. Subarrays are indeed key to how many of the array primitives operate so efficiently-- basically they point to the same data as the original array, albeit have different scalars keeping track of each dimension in the array.

    • Like 1
  3. Well I won't be spinning off a build of my code until tonight (takes too long to just "test" it), so I can't comment on if it's functional in the RTE, but I am noticing some behavior inconsistent with the documentation while in the IDE. I'm after the system pointer and the finger pointer, which according to the docs should be values of 1 and 6. Neither of those are right though, trial and error has landed me at -1 and 0 for two values.

  4. Thought I'd poll the consensus here. Has anyone had issues using the Cursor Property on picture controls while in the run-time environment? Help says it's a scripting feature, but that it is available in the RTE, which seems weird to me. Does this actually work reliably in the RTE?

    My searches aren't turning up much beyond the numerous discussions relating to the CAR where the last used cursor from the icon editor persists across all picture controls while in the IDE.

  5. You might try typcasting the timestamps as arrays of U64 and then performing addition and subtraction on those.

    Technically you ought to typecast it to a cluster of {I64, U64}. The whole seconds element is a signed value allowing for dates prior to the epoch. The fractional seconds though is indeed an unsigned integer.

    Indeed not all of the precision of the U64 is used, however this is likely a function of the timing source resolution not the format itself. My virtual machine here only reports significance in the highest three bytes, though I seem to remember my main desktop reported four bytes of resolution...

    Phillip is correct in that the format is technically capable of a time resolution of 2^-64 = 5.4 x 10^-20 s = 54 zs. You'll be hard-pressed to find hardware that can pull off precision like that for quite some time.

  6. Time is short, but I'm mostly referring to code coverage. If I test a public method, even though I may not see the private methods that the public one calls, those private execution paths are still under test. If I make a change to one of those private methods, change can still be measured through the public methods that use that private method. That difference could be faster execution time, different return values, changes in state, or even a null change-- seeing no difference is often a valid and useful metric...

  7. Indeed, the very reason I posted this was because I had a loop that the 0 ms wait didn't do the trick. The loop does wrap a CLN, but is not set to use the UI thread exclusively. Forcing a non-zero wait seems to solve the problem for me and given the maximum number of iterations I'll be bounded to isn't prohibitive, but I can imagine cases where I'd rather not have to introduce forced minimum delays.

  8. I have a Windows specific application I wrote in LabVIEW, and sometimes when I need to churn through a lot of data or become disk-bound for a while, Windows will label my application as "Not Responding". What's a good way to prevent this from happening?

    I know back in the days when I programmed using MFC it was really just a matter of making sure the main Windows messaging loop got serviced from time to time. In LabVIEW do we really have any option other than perhaps sprinkling doses of waits in our code and hoping the kernel gets called in the interim? Even in a more general sense, what's a good way to keep a host OS happy when embarking on epic journeys of computation or serialization?

  9. No, it does not force the load.

    Thanks for the info!

    With regards to testing the public API, I can't really argue because for the most part I agree this is the best way to go.

    Putting the test VIs in the class can be a real pain, for example when integrating your class in the greater whole. If during integration changes need to be made to the interface of a class member that is used in a test VI, chances are that test VI will be broken, thus your class will and your application too. So your build is broken because of the broken testcode even though all VIs actually used in the application's hierarchy are not.

    You hit on an important aspect, but it's not the only one. If testing should be concerned with the public interface and only the public interface-- no matter how low level, if I change something in the private scope it ought to make a change in the public interface if my tests are "well designed".

    However when something goes wrong, when you get a failed test and need to debug why that test failed, having tests in place to run on the private bits can be really helpful. Making that interface public just so it can be tested likely isn't the answer, no more than moving the tests into the scope of the library so it can access the private bits.

  10. If I declare foo.vi to be a friend of widget.lvclass, does foo.vi get loaded into memory when the widget class library gets loaded? Will I run into problems if foo.vi doesn't exist or can't be found at run-time?

    I'm trying to write some VIs to test some private methods of a class, but I'd rather not have these test VIs be included with the class, and I definitely don't want the methods in question to be public. My solution was to use community scope to expose the methods for testing while in the IDE, and simply not include the VIs that test the methods in any builds I distribute. Is there a better way of doing this?

  11. I speckle my code with tons of TODO comments when I develop. When I find time, I'll often do a search for "TODO" and see if I can hammer any of them out, but in LabVIEW all I get is the name of the VI of any comments the search finds containing my search text with no context as to what any of the items are (unlike say the exceptionally useful task list in Visual Studio).

    Has anyone written a tool that allows me to scrape stuff like this from my project VIs? I'm aware of the various idea exchange entries, I'm just wondering if there's anything out there that will do the job now.

    • Like 1
  12. I'm playing around with the idea of using event structures in asynchronous sub vis which take an event registration refnum as a terminal.

    My only recommendation is to never do this. Event registration refnums are strictly typed and can't be changed easily as you implied. It might seem like a minor inconvenience now, but you can really end up in a bad situation if you start passing those registration refnums all over the place.

    Plus, why would you want to pass an event registration refnum around? There should be a one-to-one relationship between event structures and registration refnums. Make a typedef cluster of your events refnums, pass those into a subvi, then obtain a registration refnum from the cluster in the same VI you need it.

  13. I don't think anyone is doubting it happens, but for the record here's a video I made a few days ago when this issue crept back up to the top of the lava feed (no idea how to embed it).

    http://www.screencast.com/t/e8szIGbKRz

    Doesn't show much, just that it happens. I sped up time during the video, but it was a few minutes of me trying to add a numeric control to a class. Got so far as to add the control and attempt to change the name. I had to kill LabVIEW.exe before I even got a chance to change the control to an I64. By the time I produced the video I had let the IDE spin for about 20 minutes before killing it, but I've let it go overnight before and it has not recovered.

    The ridiculous thing is when I went and edited the class alone, I then went back and opened up the original project and everything just worked, no big recompile times once it had to load the modified class. This is fairly typical when this happens.

    The class in the video is very simple: it has no VIs except accessors, all are static and available through property nodes; not involved in any inheritance chains (except LabVIEW Object); and I'm pretty sure none of the fields are objects so it ought not to have any class dependencies.

    • Like 2
  14. I agree completely with you Mike, I have applications where such practices have produced easily editable code at any level.

    However it doesn't help when dealing with old code where this issue already creeps up. Furthermore there are times where I'd have better luck squeezing water from a rock than getting a well defined set of requirements that will allow me to plan a proper level of abstraction from the beginning.

  15. This issue continues to be a thorn in my side as well. I have classes that simply can not be edited while in the context of larger projects. Fortunately I've managed to pull all my classes out of library scope and when I need to edit them and run into trouble, I can shut everything down, open the bare class and make changes, then reload the project. This is not a good solution-- for one I need to spend the time unloading/loading all for the most trivial changes. More importantly is it precludes renaming anything, so I end up with absurdly named items and a legacy of orphaned/deprecated members since what I really want to do is change/move something but I can't...

    If NI really doesn't see this issue often enough, I imagine I can throw my code into a package and sent it off to them, but I'm not even convinced any of these issues are that reproducible as I can go hours making some rather drastic changes to my classes, only to have the IDE choke up on something as simple as changing an I32 to an I64.

  16. I wasn't clear on this before, either. What can I leave in dependencies? Some of the classes explicitly contained in the project have parents that weren't. There was some reuse code in dependencies, too. I've moved all but the instr.lib, user.lib, and vi.lib into the project just to be safe, but I thought the build would capture them.

    Sorry about the confusion, when I said "that need to be brought into the project" I didn't mean you need to do so, I meant that the development environment needs to bring into memory to successfully load all of your project items.

    Just because your project contains items doesn't mean they will be included in any build specifications you make in that project.

    My projects are usually littered with many test VIs that I use to validate functionality, run unit tests, demonstrate proof of principle, etc. They do not go into the build because they are not part of the core code. Some projects also have many different build specifications, such that different components from the project go into different executables.

    The dependency tree in the project explorer though is very useful because once you have something in your project, you're telling LabVIEW, "Hey, I'm going to use this widget somewhere!" and it will do it's best to figure out what else it needs to bring along for the ride. If you go ahead and plop that widget down on a block diagram of a VI that goes into your application, LabVIEW will bring along all the dependencies it can figure out automatically. But if you dynamically load that widget and there's no static link from your application to that widget, LabVIEW will be clueless about the relationship and you'll need to manage it yourself. Similarly if you use something like a DLL, LabVIEW will know about the DLL if you use it somewhere, but who is to say that DLL doesn't dynamically link to other DLLs? (This is where the MSVC dependency has bitten me many times over.)

    You can generally leave as much as you want in dependencies, there's nothing wrong with that and I'm sorry if I implied you should not do so. The trick to the dependency tree is using it to track down items which you might need to include into your builds which you would otherwise be unaware.

  17. Are you running the executable on the same computer as the development environment?

    These issues can be really tough to debug. For me it always end up being unresolved dependencies which are either not distributed with the executable, or system level libraries that are unavailable. Basically the executable was successfully built and there's nothing wrong with it, but it's not until you try to run it that you find out something critical is missing.

    You may not have explicitly included external dependencies or done any dynamic loading, however are you sure the emulators don't do as much? Or other code you may use?

    One trick you can play is this: open your LabVIEW project and look at your Dependencies. If you don't see the dependencies in the project explorer, make sure the menu item Project: Filter View: Dependencies is checked.

    There you should see anything that your project uses which isn't explicitly included in your project. You can probably ignore the things in user.lib and vi.lib, but you may also see things like some DLLs or .NET assembly references here that need to be brought into the project.

    If you find dependencies, is it a system-level library? Stuff like kernel32.dll, or other Windows components. Chances are you won't need to worry about these, although they may restrict which operating systems you can use your executable on. If it's not a system-level dependency, make sure it gets included in your build. LabVIEW will usually pull any of these into a build automatically, but dynamic loading can leave no clear traceable path to them and easily result in them not being picked up when building.

    As an aside, a few stabs in the dark. Two issues I've repeatedly run into:

    1. Various flavors of the Microsoft Visual C/C++ runtimes not being available on the system. Despite what many people think, there is an RTE for the various MSVx incarnations (just like there is LabVIEW), they're just so common may people forget about it.
    2. If any LabVIEW code uses .NET (either your code or third party code), you'll be needing a .NET 2.0 compatible installation. That would be any of the 2.0, 3.0, or 3.5 installations as they're all additive and include 2.0-- but beware later versions do not.

    • Like 1
  18. Hehe, I already poke around the registry to obtain a font list. I'm not sure I like the idea of testing individual fonts, not only is it slow, but it doesn't help if I want to distinguish serif from sans-serif, for example. Granted, for this application all I care about is monospace...

    Dug this up while poking about the MSDN:

    post-11742-0-58487500-1347288191.png

    Windows specific, but seems to work.

  19. Does LabVIEW have any capacity to resolve font types? That is say I want a text box to be monospace, or sans-serif, but really don't care what the exact font is. Is there a way for me to set this and just let the IDE figure out what the system defaults are?

    I'm pretty sure the answer is no, but lava often surprises me.

  20. Consider this fairly typical scenario:

    • You need to create an array of data.
    • You know an upper bounds of how large that array can get.
    • It's computationally expensive to determine the exact size you'll need before hand.

    Usually getting this done is just a matter of initializing an array to the boundary size, filling it in a loop, then truncating the array when I'm done my calculations and know the exact size.

    post-11742-0-20687400-1346443620.png

    However, that's a fair amount of code, things can get a little messy when real calculations are being performed. I'm wondering if we use a conditional for loop, does the compiler produce pretty much the same operations?

    post-11742-0-97035300-1346443626.png

    That is since the for loop is bounded by a Max Size, will the compiler initially allocate an array of that size, then truncate at the end? Or will the operation be analogous to indexing an output on a while loop where the array keeps growing as it needs resizing?

    Oops, I forgot to add bounds checking to the while loop snippet...you get the idea. Just imagine the conditional terminal had an additional AND operation in there to check the index, and the resize operation took into account whether the last iteration was successful or not.

    • Like 1
×
×
  • Create New...

Important Information

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