asbo Posted January 25, 2012 Report Share Posted January 25, 2012 Keep in mind that this method will be slow for large objects because it uses Flatten to String. In any case, I would think that parsing the string would be easier than trying to walk the byte array, but if it works, it works. Quote Link to comment
Aristos Queue Posted January 26, 2012 Report Share Posted January 26, 2012 Well, in any case, it looks like the OpenG version is considerably faster (I see ~20 ms for OpenG vs. ~300 ms for the vi.lib VI), so that answers that, at least. Ah, the int16 array. How... quaint.There are many types created since LV 8.0 that cannot be represented in the int16 array, and even some older types aren't guaranteed to be represented correctly under various conditions (enum, for example, if there are too many characters in the total concatenated list of strings). The variant type library in vi.lib is the type library of LabVIEW. The Int16 array is no longer maintained for new types, and hasn't been for years. Yes, it still works on many, even most, types, but it isn't what I would suggest you use, certainly not in the long run. 1 Quote Link to comment
drjdpowell Posted January 27, 2012 Report Share Posted January 27, 2012 (edited) The variant type library in vi.lib is the type library of LabVIEW. The Int16 array is no longer maintained for new types, and hasn't been for years. Yes, it still works on many, even most, types, but it isn't what I would suggest you use, certainly not in the long run. Are there plans to improve the performance of the VariantType library? The few VIs I’ve tested seem to be about an order of magnitude slower than equivalent OpenG functionality based on parsing the Int16 type array. I never use them as result. — James Edited January 27, 2012 by drjdpowell Quote Link to comment
Aristos Queue Posted January 27, 2012 Report Share Posted January 27, 2012 Are there plans to improve the performance of the VariantType library? The few VIs I’ve tested seem to be about an order of magnitude slower than equivalent OpenG functionality based on parsing the Int16 type array. I never use them as result. — James No, there are no such plans. They've never been identified as an API in need of high performance. Quote Link to comment
drjdpowell Posted January 28, 2012 Report Share Posted January 28, 2012 (edited) No, there are no such plans. They've never been identified as an API in need of high performance. OpenG it is then. Who’d have thunk flattening and parsing would be the “high performance” method. — James Edited January 28, 2012 by drjdpowell Quote Link to comment
ShaunR Posted January 28, 2012 Report Share Posted January 28, 2012 Yes, the VIs that ship with LabVIEW do support determining if a variant contains an LVClass instance. I'm fine using this where needed, but I'd love to have a native implementation in the OpenG LabVIEW Data Tools Library. Native implementation, to me, means that it uses primitives other than a Call Library Function or Code Interface Node (unless it's to call to LabVIEW.exe and the code is guaranteed to work at Run Time in both desktop and real-time). I guess I don't really trust stuff that's inside password protected VIs and that's not in the palette. It could get removed or put into an LVLIB and scoped as private Me neither. Quote Link to comment
drjdpowell Posted January 28, 2012 Report Share Posted January 28, 2012 (edited) Strange. I put ShaunR’s VI (which seems to just call into LabVIEW.dll) into my speed tests using small objects, and it executes in about 8 microseconds, while the “GetTypeInfo” VI (the password protected one, which I would have thought does exactly the same thing) executes in 240 microseconds!!! Comparable OpenG functionality (based on the int16 type array) executes in 22 microseconds. I wonder what extra overhead is in that password-protected VI? — James Edited January 28, 2012 by drjdpowell Quote Link to comment
Aristos Queue Posted January 29, 2012 Report Share Posted January 29, 2012 Debugging enabled? Front panels closed and unloaded? Inlining? Quote Link to comment
drjdpowell Posted January 29, 2012 Report Share Posted January 29, 2012 (edited) Debugging enabled? Front panels closed and unloaded? Inlining? I tried making Shaun’s VI normal priority, not inlined, debugging on, and non-reentrant with the FP open: only slowed it down to 18 microseconds. So that isn’t it. Edited January 29, 2012 by drjdpowell Quote Link to comment
ShaunR Posted January 30, 2012 Report Share Posted January 30, 2012 I wonder what extra overhead is in that password-protected VI? Perhaps it has longer wires or more wire bends restricting the dataflow Quote Link to comment
drjdpowell Posted January 30, 2012 Report Share Posted January 30, 2012 Perhaps it has longer wires or more wire bends restricting the dataflow Takes a coffee break half way though. NI’s not paying it enough for “high performance”. 1 Quote Link to comment
Darin Posted January 30, 2012 Report Share Posted January 30, 2012 Clearly the fact that Shaun's code stubs the TypedefInfo Constant into the first Case Structure makes a huge speed impact. Actually, the two things that jump out at me are that the LV version stubs the variant as opposed to passing it through with the control and indicator on the root diagram like Shaun does (doubt it makes a difference on small items though), and that Shaun configures the CLFN to use any thread, perhaps the LV one uses the UI thread and this takes its toll (pesky default behavior). Quote Link to comment
drjdpowell Posted January 30, 2012 Report Share Posted January 30, 2012 I noticed that the first call to either “GetTypeInfo” or “Get LV Class Path” is very slow, between 3 and 16 milliseconds, but only for the first one of the two called. So they must both access the same (very slow on first call) thing. Quick Tests: 1) Stub the Variant —> faster 2) set UI Thread —> much slower! That could be it. Quote Link to comment
mje Posted January 30, 2012 Report Share Posted January 30, 2012 ...and that Shaun configures the CLFN to use any thread, perhaps the LV one uses the UI thread and this takes its toll (pesky default behavior). That would be enough to make me nervous. I consider it best practice to leave all DLL calls in the UI thread unless the call you're making has explicit documentation stating it is "thread safe". Otherwise, correct me if I'm wrong, nothing is stopping LabVIEW from making parallel calls to the DLL which might stomp on some static memory. Maybe that's just a legacy of my C days and I'm being a curmudgeon, but my understanding is that's why the UI thread is the default for CLFN nodes? Now I do trust Shaun quite a bit, but he's not NI so I doubt he knows exactly what's going on under the hood of that call... Quote Link to comment
ShaunR Posted January 31, 2012 Report Share Posted January 31, 2012 (edited) That would be enough to make me nervous. I consider it best practice to leave all DLL calls in the UI thread unless the call you're making has explicit documentation stating it is "thread safe". Otherwise, correct me if I'm wrong, nothing is stopping LabVIEW from making parallel calls to the DLL which might stomp on some static memory. Maybe that's just a legacy of my C days and I'm being a curmudgeon, but my understanding is that's why the UI thread is the default for CLFN nodes? Now I do trust Shaun quite a bit, but he's not NI so I doubt he knows exactly what's going on under the hood of that call... It's a good point. I have never seen it defined explicitly that "all LabVIEW.exe calls are thread-safe" (perhaps someone from NI could clarify). Or indeed (by extension) a definition of those that were or were not. However, thread safety is usually defined on a per dll (or in this case per exe) basis. So if the LabVIEW.exe wasn't thread-safe. I think we would all be in trouble. Anecdotally, I have never run into any problems assuming it is. Thats not to say that NI have not ensured all calls are indeed thread-safe on the assumption that no-one outside of NI without the internal knowledge as to what call is and isn't thread-safe. But I would be very, very surprised if they were mixed and matched within the exe. Saying that. Calls to the labVIEW.exe that involve the user interface I do not make re-entrant on the assumption that it is a call within the UI thread. So if any were going to be an exception, it would probably be those. Edited January 31, 2012 by ShaunR Quote Link to comment
ShaunR Posted January 31, 2012 Report Share Posted January 31, 2012 (edited) Oh. And as an after-thought (an after I can edit, thought ). The reason for posting wasn't to provide a "faster" version of the NI one (thats more by accident since I didn't benchmark it). Just a version that you could see the diagram - Jims request, Feel free to change the calls to UI if it makes you happier because with this offering you can Edited January 31, 2012 by ShaunR Quote Link to comment
mje Posted January 31, 2012 Report Share Posted January 31, 2012 Oh. And as an after-thought (an after I can edit, thought ). The reason for posting wasn't to provide a "faster" version of the NI one (thats more by accident since I didn't benchmark it). Just a version that you could see the diagram - Jims request, Feel free to change the calls to UI if it makes you happier because with this offering you can LOL. I would. And I understood the example as how to check for classes, not an attempt at proving speed. But in all seriousness, thank you for posting that example, I've never even tried making calls directly to LabVIEW from the CLFN node. I always wondered how to do it in such a way that it automatically worked both in the IDE and RTE. I take it by referencing the library simply as "LabVIEW", that everything sorts itself out when compiled? However, thread safety is usually defined on a per dll (or in this case per exe) basis. So if the LabVIEW.exe wasn't thread-safe. I think we would all be in trouble. Anecdotally, I have never run into any problems assuming it is. While I don't doubt that entire libraries or executables can be declared thread safe, it's not an automatic type of thing. Just because one call is thread safe does not make another. Any code which accesses dynamic shared memory (values that can change) in an unprotected manner can (not will, but can) lead to potential problems. Shared memory can be globals, static* memory within a function, or perhaps be related to hardware access. The problem, and reason multithreading programming is "hard" is that these accesses can be buried so deep in the function stack that they can be invisible to anyone using a given API. It's even worse that offending code can appear stable until that one time threads collide in just the wrong time, of course in an unpredictable and non-reproducible way. LabVIEW of course makes most of this completely moot when you stick to an entirely by-value architecture, but I don't need to mention there are many things in LabVIEW which aren't by-value. Saying that. Calls to the labVIEW.exe that involve the user interface I do not make re-entrant on the assumption that it is a call within the UI thread. Agreed, there's no point in making the VI re-entrant if the clones would need to wait for access to the same thread. *Static is a term that is somewhat foreign to LabVIEW, but think of things like shift registers, feedback nodes, or LV2 globals, etc. Quote Link to comment
ned Posted January 31, 2012 Report Share Posted January 31, 2012 That would be enough to make me nervous. I consider it best practice to leave all DLL calls in the UI thread unless the call you're making has explicit documentation stating it is "thread safe". Otherwise, correct me if I'm wrong, nothing is stopping LabVIEW from making parallel calls to the DLL which might stomp on some static memory. A bit of a side note, but if you have a DLL that is not thread-safe, you can still configure it to be called in any thread so long as you ensure yourself that it cannot be called multiple times in parallel. The easiest way to do that is to wrap it in a VI that isn't reentrant. 1 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.