Jump to content

LAVA 1.0 Content

Members
  • Posts

    2,739
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by LAVA 1.0 Content

  1. Not a complete editor, but you certainly can do a lot programatically with colors and fonts, see the PJM Blog post HERE
  2. It doesn't stand for State of California Auto Dismantlers Association? Bang, bang!
  3. But in OO someone can always create a dynamic VI that overrides your method that doesn't need locking. If you don't have locking mechanism available in the base class, then override method that would need it cannot operate.
  4. Use match reguar expression node and cofigure it so that it matches the things you want to remove. Then run it in a loop as long as it matches something. To learn regular expressions check this very good web site.
  5. Sounds like a bug to me. I wonder if this bug exists also for queues and other inter-thread communication nodes.
  6. BOOKMARK THIS POST. I WILL ADD NEW IMAGES TO THE TOP SO YOU DON'T HAVE TO HUNT FOR THEM Right click and "copy location" then go back to your post and click | | | | | | | EDITED Oct 20,2006: I often see comments like (coffee emoticon here) or something like that, and I've even seen my "throw" LV8 project icon on the NI forums. (Not that there's anything wrong with that ) How about a thread where we can keep a few of these emoticons handy? I'll start by adding my LV8 project emoticon, and a coffee cup that was posted recently. Firefox users can right-click on the image, select "Copy Image Location", and then use the "Insert Image" function to include in your post. Oh, and let's keep it LAVA oriented (anyone can Google "emoticon" and cut and paste), keep it CLEAN and most of all FUN! Also, I've mentioned myself that a NI bird emoticon would be nice, but let's not make trouble by infringing on copyrights. Throw LabVIEW 8 Project emoticonCoffee Cup emoticon (PS. Make sure that you upload the image; don't link to off-site artwork.)
  7. JFM, thanks for your comments. I don't really understand why it should behave the way you describe. I can first create a notification, then open a VI reference, then pass the notification to this VI and let this VI wait for the notification. I tested it and it works (see the attachment below). Therefore it shouldn't matter if I send the notification before all the reentrant VI instances are ready to wait for it; they should be able to catch the notification later on as they are ready. After all I don't destroy the any of the notifiers until in the very end. Therefore the notifiers should stay present as instance VIs come and go. About the step 3 loop, it doesn't require the notifications to arrive in certain order as long as all of the return notification arrive. It goes trough them in certain order, but it all notification eventually arrive no matter which order, the loop should pass. Download File:post-4014-1159812121.zip
  8. I have some problems with notifiers. The more I have communication trough the notifiers, the more there seems to be missed notifications; although I see no reason they really should be missed. The misses disappear if the program execution speed is slowed down. I attatch the following LabVIEW 8.0 project that represents the problem. Open the project and run the file "Test Scalability.vi". When it's ran on my computer, it runs some iterations and then freezes because it fails to catch a notification or a notification is not properly send. The reason it freezes it not completely clear to me. The problem may be either in the notification system or even in the scheduler or there could be a bug in my code that I fail to find. EDIT: I forgot, I tested and the behaviour is still present in LabVIEW 8.20. Download File:post-4014-1159808271.zip
  9. I worked in an accredited calibration facility for some time, and we used SI notation and SPACES between the elements. It made displaying the values for standard capacitors and resistors much easier (less chance of losing your place). I was always formatting to string; it would have been nice to have a format style like this... 10.000 001 2 MOhm is much easier (at least for me) to read/transcribe than 10.0000012 MOhm
  10. See this thread for details... Queues appear to be implemented as a circular in-memory buffer. There is no way to define the "when full" behaviour of a queue. The current solution from the producer side is to to enqueue -> timeout -> dequeue element -> enqueue element; or get Queue Status, dequeue element if full, enqueue element. Specifically, I've been finding fairly frequent need for a behavior more like lossy circular buffering. I'd like to fix the size of the circular buffer, and then the freshest data keeps circularly overwriting the oldest data. The UI thread could then asynchronously perform analysis on the most recent N samples, acting like a sliding window. (Kevin P.)
  11. To increase the performance of get-modify-pass sequence I wrote a semaphore based on the ideas of besvingen's pointer system. I submitted it to the repository, it'll appear if the admins accept it.
  12. Variants are better for in-memory usage performance wise. Flattened strings suit better for storing data to disk etc. Variants are also more flexible in many ways. There was some discussion and examples of benefits of variants over typecasting in this thread.
  13. First, you could just drop it to the block diagram of itself, no need to open VI reference. Second VI reference is currently opened somehow inefectively using path as a key; stateless VI code would be in memory already in compile time and only the dataspace needs to be duplicated. It's not different from duplicating a buffer at wire branch. Third stateless VI dataspace cannot be accessed from outside the current instance of the VI. This makes it possible for the compiler to compile more effective code since it doesn't need to allow the VI to be accessed asynchronously by other concurrent threads. So single instance of stateless VI can in principle ran as effectively as a single threaded program - there is no need for synchronizing the data between the threads or even leaving doors open for that.
  14. I use LV 8.0.1 and 8.2. The new lvlib libraries and lvclass classes provide namespace for the items they contain. So I use these two to define the namespaces for my VIs.
  15. ...assuming units in which 4 pi epsilon0 = 1.
  16. Well, you just need to initialize a new dataspace for each call and flush it when call exits. So each call would have a separate dataspace. At least other programming languages perform in this task much better than LabVIEW with open VI reference.
  17. My sentence was not the best possible. I didn't really refer to random access of get and set operations but to create and dispose operations in random order. There is this search array which performs probably O(N) so in natural system the creation will scale O(N) over the number of pointers in the system. You can decrease this to O(1) by keeping track of disposed pointer indeces in the boolean array. For small arrays this could however be slower. Perhaps you understood me wrong. When user calls the Get Data operation, he gets the content of the stack but the data stays also in the stack. If the user wants to modify the data in the stack, he/she needs to get the data using Get Data, then modify it outside your VIs, and then write it back. During this time some other VI may try to do the same thing. So you get exactly the same kind of competition as you get with multiple threads in a conventional programming language. However, in conventional language you can easily control the number of concurrent threads but in LabVIEW you cannot. So to guarantee that the data doesn't change when a VI is modifying the data, it needs to acquire a semaphore to the data. That is to build a complete system you also need to create a semaphore system that blocks the access to specific pointer when another thread has acquited a semaphore for the same pointer. To build a semaphore system you either have to use LV queues, LV semaphores or you have to write a reentrant VI that keeps calling Global Storage__P.vi in a loop until the pointer is released. The two first alternatives make your pointer system perform poorer than LV queues and the last alternative scales very badly with the number of simultanous data access to any pointer in the system. However you pointer system performs very very well in a situation when concurrent read-modify-write is not needed. LabVIEW probably uses C++ queue to control access to your Global Storage__P.vi. Only one thread at a time can access it, as it is not reentrant. And you naturally cannot make it reentrant. Open VI reference to N instances of a same VI that tries to use your pointers to perform something. Then increase N and see how it scales.
  18. Because of the high performance gain the can be achieved and the ability to make recursive calls. Take a look at my entry at wish list.
  19. My third post for Santa this friday. This is really something I've been wanting to see in LabVIEW for some time now. Polymorpic types First of all, I'd like to see polymorphic types. What I mean with this is the following. One should be able to define front panel terminals that are of multiple types simultanously. These terminals would accept all these types of data. Wire propagating from such a terminal could be connected to any node that would accept at least the same types, but could also accept some more types. One can implement such a polymorphic types in a bit similar fashion as enums or arrays are implemented. A polymorphic type controller would be an "type-array" each element of which would be a type specifier. One could also drop another polymorphic type-array into such array so that the resulting polymorphism would include all the items of the array itself and all its subarrays and their subarrays and so on. The "type-array" would be structurally a tree and the polymorphic type of such a tree would be defined by flattening the tree into a set of all the nodes in the tree. Type classes Types should form hierarchies, that is type classes. For example Integer and Floating would be subtypes of general class Number. Furthermore I32 and I16 would be subtypes of Integer type. You could define that your terminal is of type Integer and would therefore accept both I32 and I16 inputs without coercion. The type classes shold in the beginning be built-in only. That is, user couldn't add new members to built-in type classes. Later on however, users should be able to extend type classes by defining own type that belong to certain type class. Type classes are exactly specified by requiring that certain built-in operations are defined for the type. For example a type of class number must have addition, substraction and multiplication defined. Type of class Floating should in addition have division operation defined. Type classes, polymorphic types, type propagation and dynamic dispatching Type propagation of polymorphic types and type classes is somewhat similar issue to type propagation of LVOOP classes. When you wire two DBLs to your "+" operation, you want the output to be DBL. That means that the correct instance of operations should be decided at run-time not compile time. Since the same type often propagates trough multiple subVIs and multiple nodes, not all of these need to be dynamically dispatched one-by-one. Rather a whole block depending only on one type can be dispatched as an entity. If the correct block to be dispatched depends on multiple types, then probably the safest thing to do is to call the correct operation one-by-one. Roadmap Now that we have defined polymorphic types and type-classes, we still need to add wires and extend types so that wires can propagate not only VI references but block-diagrams themselves. We also need totally stateless VIs, real recursion (without opening a VI reference first), local and global variables that can only be written once (i.e. they are also stateless), perhaps lazy evaluation and some kind of lamda calculus, type pattern matching similar to Haskell counterpart and we end up in a fully featured graphical functional programming language. Monads are not needed, since empty wires or something like error cluster can define the execution order for I/O and user interface operations. Loops can be used in dataflow version of functional programming language, as they do not require variables unlike loops in text based programming languages. This kind of general purpose programming language would probably be the most advanced, easiest to use programming language in the world. It would be naturally multithreading and allow writing highly modular code. I think combining dataflow programming language and functional programming language results in a something really amazing. It's a pity that I know National Instruments will never ever do this kind of general purpose programming language. Perhaps I do it myself. Anybody else interested in joining my... quite challenging effort tongue.gif
  20. I've been discussing this feature already earlier in some other thread but perhaps I raise this up also here... What I'd really like to see in LabVIEW are stateless VIs. I don't mean that all VIs need to be stateless but there should be a new kind of execution option "Stateless VI". With stateless VIs I mean that the VIs would have absolutely no state. At runtime they would of course have dataspace, but once call has exited, the dataspace would be cleared. This meands that these VIs would have no uninitialized shift registers, no front panel components would contain any values, there would be no local variables, all front panel components would need to be connected to connector pane inputs would need to be connected (outputs can be disposed at call exit). Why all these limitations? Well, first of all if VI would be stateless, it could call itself recursively, so real recursion without open VI reference would be allowed resulting in much faster and easier recursion. Second stateless VIs wouldn't have persistent dataspace meaning that the same VI could easily have as many instances as required for effiecient runtime performance. There would never be waiting for the VI to become free from another call, it would always be free and ready to run. There would be no need to find out if the VI is free but the VI could just be run the VI. The compiler didn't even have to keep the VI as a separate module but it could build much more efficient code by optimizing over VI barriers. All this and probably even much more that I cannot think of results in much higher performance, dataflow in it's purest sence. Even besvingen would probably be satisfied with the new increased performance. This would also bring LabVIEW more closer to functional programming language, which is very powerful programming paradigm.
  21. How about very irritating blinking and beeping loop terminal, you can't help noticing it. If it would still have a such a black hole effect that it would such the mouse cursor passing by, it would defenitely be noticed. :laugh: :headbang: Seriously, there should defenitely be a visible difference between these two kinds of terminals. And really not blinking...
  22. Hi besvingen, I had time to take first deeper look at your code. The idea looks cool and the implementation is pretty efficient. I've a few comments that I think should be considered. First when you dispose your pointers, I think you should store these disposed pointers into an array. This way when you need a new pointer, you could just pick the last disposed pointer from the array. As with heap, the array should be initialized to some default value to avoid resizing. I thinkg this will increase random-access performance. Which leads us to the second comment. Your performance measurement wasn't about random access but about create, set, get, destroy in a sequence. So you don't really measure random access performance i.e. the case when you create and dispose pointers in random order. Now you first create all pointers and then dispose all pointers. That's not what happens in a normal programming environment. Also you should do much more get and set operations per each creation and destruction for the performance measurement to be more realistic. You always use your pointer for many operations in reality rather than dispose it almost immediately. Third issue is related to concurrency. Your pointer system doesn't seem to have concurrency control other than the fact that only one thread can access the VI at a time. This however is not enough in most of the cases. You'll rather have a sequence get - modify - set. Your system allows data corruption in such scenratio where two threads allow to get - modify - set the same data simultaneously. The queue has a built-in locking mechanism that protects against this issue. Fourth comment relates to performance in concurrent situations. It's not evident to me that this system performs as well as it does now if there are concurrent access to the stack. Queues only keep a lock to a single instance of data. This mechanism locks the whole stack when ever any thread tries to access the stack. This means that the stack scales less efficiently compared to queues when the number of acquired pointers increases in non-sequential system. Overall, a very nice idea though I don't want to sound negative, these are just things that came into my mind and I think it may help to develop the concept if I share these ideas.
  23. Hi, I'd appreciate the following functionality. When initializing the shift register outside the loop, the developers should be able to define if the shift register will be initialized only for the first call or for each call of the containing VI. This way the first call? case strucure inside the loop would be unnecessary. There is also another advantage. In the future there may be labview data types like objects and references that always need initialization. For objects developer defined constructor may need to be called and references naturally need to point to something to be properly initialized. If there would be a possibility to have LV2 style globals that would still always be initialized, then these globals could also be used with data types that require initialization. Compiler could generate an error if developer tries to wire such a type to a normal uninitialized shiftregister. Third, this kind of initialization makes it possible for the compiler to generate a slightly more efficient code. As a summary, loop left side shift registers should have a context menu option to define if the shift register will be initialized from outside the loop for each call or only for the first call. At persent all initialized shift registers are initialized for each call and to initialize only for the first call a separate "first call?" strucure is needed inside the loop.
  24. Hi Marcus! Quite a detour to get in touch! Hope all is well! I hope this thread will live on for a while, and that more people perhaps would comment on how to tame the "beast of complexity". Wikipedia has some background information on state diagrams: Wikipedia - State diagram We also have an ad here at LAVA for the LabHSM toolkit: LAVA LabHSM This toolkit looks like a very nice tool, but it lacks the ability to define the hierarchial state machines graphically. I really like the notion of defining the architecture graphically. Wouldn't it be possible to run the application with a kind of "execution highligt" at this level? Showing you in some fanciful way, the inputs, outputs and state transitions. As always, it's just a SMOP. //Lars-G
×
×
  • Create New...

Important Information

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