Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by bsvingen

  1. Good catch However, IMO it is not a bug, but simply a natural feature of pointers. It is best to think of the LV2 global as a block of Random Access Memory (RAM). The LV2 global does in fact simulate a block of RAM, and the pointer is just an int32, an address to an arbitrary place in the RAM. There is no connection what so ever between the data stored in the address and the pointer that has this address as a value, other than the fact that the data happends to be stored at the location that the pointer points to. What happends in your example is that you allocate one slot in RAM and receives a pointer (the address) to that slot. Then you get the data, AND you copy the pointer (the address) by branching the wire. Then you dispose the data and the pointer. However, disposing a pointer means only that it does not anymore (neccesarily) point to the data that it first was set to point to. In the implementation it means that the data the pointer is pointing to is destroyd, but it does not mean that the location in RAM (the address) is destroyd, just as physical ram is not destroyd. Since you have disposed the pointer/data relationship, it is now possible to allocate that address again and put other data into it. So your second pointer now has the same address as the first pointer, and the value they are pointing to must of cource be identical. The same thing will happen in any other language that support pointers when you copy pointer. of cource. It is strange how sometimes the obvious solution just does not occur
  2. I have made a variant version earlier, it can be found here. It is only for LV8.2 since it also uses LVOOP as a class for the reference. This pointer version is really only a stripped down version of the variant ref, with the aim of making references to data as efficient as possible. I have done some (very preliminary) thoughts about using names. So far I just can't see how this can be done without adding a lot of overhead and difficulties. It will require a lookup table of some sort to be efficient (hash table or binary tree). The only primitives i know that has efficient lookup tables built in is queues and variant attributes, and i therefore think that such a system would have to include either one of those primitives built into the LV2 global or instead of the LV2 global (maybe some sort of dqGOOP style system that i have seen examples of here on the board). Either way, a lot of overhead is added when using names, since that name needs to be "dechiphered" in some way no matter how you look at it. Probably? the most efficient way to use naming as the "reference", and if you are not too concerned about actually obtaining a "wireable" reference, is to put one single Variant in a LV2 global and set all your data as attributes in the Variant. Then you have named globals that can take any type. I have tested the variant attributes as a lookup table, and it is incredible efficient.
  3. File Name: Pointer System File Submitter: bsvingen File Submitted: 18 Sep 2006 File Updated: 29 Sep 2006 File Category: LabVIEW OOP (GOOP) Pointer System V1.1.2 Author: bsvingen - Bjornar Svingen bjornar.svingen@ktv.no Distribution: This code was downloaded from: http://forums.lavag.org/index.php?automodule=downloads Description: A set of VIs that creates and controls pointer-data pairs. The basic idea is to simulate random access memory and malloc()/free() by using one single LV2 style global. The data type must specified in "..\Pointer\Data Typedef\Data Typedef__P.vi", or it can be replaced with an LVOOP class for LV 8.2. The only restriction to the number of references is the physical memory on the computer. The global stores data in an Array and uses a separate Bool Array to control access and free/protect the data. The "address" to the data is returned directly with no type conversion (int32). Basicly the LV2 global takes data as input, put the data in an array within the global and returns the index where the data is set. This index therefore becomes a pointer to the data, and can be used later to set and get data. The upper 8 bits of the pointer is used as a counter that is incremented by one for each new "dispose pointer" call. The "Get" and "Set" function checks these 8 bits in the pointer with corresponding counter array and throws an error if they are not equal. By doing this an error is thrown when trying to use a disposed pointer. Thanks to JFM for the counter code. Due to the inherent effectiveness of LV2 style globals and no type conversions, this method is twice as efficient as using queue primitives, see examples provided. Functions such as New, Get, Set etc can be found in the ..\Pointer folder. A project file is also provided for LV 8.x. A more general system that takes arbitrary types is called General Reference System and can be found on this Code repository. In contrast to queues that can be regarded as synchronous references to data, this reference system is fully asynchronous. Allocation and freeing of data is done dynamically. Allthough this pointer system may at first glance have some resemblence to "classic" GOOP, it is by no means a GOOP system. This pointer system is best regarded as a normal LV2 global, but with the difference that it returns a pointer (index) to the data, and therefore can be used for an arbitrary number of data. All the VIs in the library are documented. Support: If you have any problems with this code or want to suggest features: http://forums.lavag.org/index.php?showtopic=4131 Version History: 1.1.2 Fixed "dispose pointer" and "obtain pointer from pointer". Some other small fixes. 1.1.1 Updated the counter so it will increment at each "dispose pointer" instead of "obtain pointer". 1.1.0 Updated the pointers so that the upper 8 bits is uses as a counter. Using a disposed pointer will therefore create an error. Thanks to JFM. Updated the allocation routine so 100 elements are added in one chunk. Thanks to JFM. 1.0.1 Updated this readme.txt file Fixed a bug in "Obtain P from P" function in the global. Added a placeholder VI (for easier conversion to LV7) 1.0.0: Initial release of the code. License: Creative Commons Attribution 2.5 License Click here to download this file
  4. Yea, maybe a good name for the oututs would be: R(eminder) and I(nteger)Q(uotient) :beer:
  5. R = x - y*floor(x/y) IQ = floor(x/y) floor() rounds the value down to the nearest integer.
  6. I have one example in the other thread here. It is the last one called Pointers Typedef V02.zip and can quiclly be modded to variant type. However, i think a linked list class would be made in a more elegant manner directly into the global using the same technique as the reference global, but with two extra arrays inside used as pointers to "next" and "previous" (for a doubly linked list or binary tree).
  7. I think i remember that daqmx8.3 is will only work (install) for lv7.1 and up.
  8. To me this looks pretty much as associative Arrays with string as the key. Why not built this mechanism into the ordinary array functions? That is where it belongs. Or parhaps better, make some associative array functions. Also, if you use a flattened to string as the key/name, it will in all respect become an associative array that can take anything as the key. Maybe a good OpenG Project :question: :2cents:
  9. Yes, I see now that optimization is one thing. Maybe inlining by the compiler ?
  10. Well, whatever you decide doing please don't change anything in LV simply because it does not fit into a puristic idiology of some programming concept and/or have side effects that may be "misused" (whatever that is supposed to mean). Shift registers (initialized or not) and LV2 style globals is probably the single most important reason why it is possible to do anything in LV besides passing data linearly down a wire from A to B via function Z(A). In the end it all boils down to getting real world results (on all levels).
  11. I think the marked is (semi) remote logging sending a file every now and then. Even today there are many applications that use mobile phone technology, especially in security (home burglar alarms for instance). Anyway, it's not easy to understand business desitions. Palm for instance. I have a Tungsten T3 that I bought 2 years ago. It has everything i need (large screen, very powerfull CPU, lots of ram, bt) but it lacks a phone. Instead of adding a phone into that casing, Palm has chosen to go forward with their Treo smartphones. The problem is that the Treo is no match for Nokia and Sony Ericsson having much better phone technology and more functionality built into them. So no one is considering bying a Treo as a phone because it is a very poor choice compared with other manufacturers of smart phones, and no one is considering bying a Palm PDA because it has no phone. Pretty soon, due to lack of a real Palm with a phone, my Palm T3 will be retired as GPS only device and my "old" 3G SE phone will be replaced by a SE/Nokia smart phone.
  12. I think this would be totally impossible. As we all know LabVIEW is a dataflow language, sending values across wires. Mobile technology is wireless
  13. Here is a tool I made with the inline script method.
  14. I'm just curious to why you are uninstalling 8.0. The ability to have several LV versions and change between them at will, is probably one of the really strong things about LV. I have 6.1, 7.0, 7.1.1, 8.0.1 and 8.2 on the same PC.
  15. I think this example show all too obvious why dataflow is not exactly rocket science in terms of compiler technology/programming paradigm. In my first larger project i was wondering about the exact same thing. I had one loop for logging and one loop for several PID controllers. The PID loop was run at a much slower rate than the logging, but at a steady rate independent of the logging loop which would change rate according to user specifications. I also ended up with using global variables, even though the manuals also back then said "use globals only when neccesary because they are inefficient and will break the data flow" or something like that + "dataflow make parallell operations easy and fool proof". 1. You cannot pass data out of a loop without breaking the dataflow. 2. The only way to run in parallel is to break the dataflow. So that dataflow really makes parallel operations easy and straight forward is some big myth IMHO. Dataflow just as often prevent parallel operation where parallel operation are the only natural thing to do. With queues, goop, lcod etc all this is now more or less an academic discussion, except for newecomers to labview, and it is therefore a bit strange that NI still advocated that dataflow is THE big thing for parallel programming. :beer:
  16. I have allways thought that you germans wanted it "nicht schnell, aber pl
  17. To me the most usable feature of LV8 was the ability to open separate FP for each instance of a reentrant VI. This enables using the BD in much the same way as simulink for instance (you can run applications directly in the block diagram).
  18. I have updated the pointer system a bit. This version is made for a strict typedef (see project explorer). I have also included a linked list that is made with this pointers. A linked list consist of a structure (a cluster) that has one or more pointers that point to other clusters of the same kind. With linked lists one typically can build trees, stacks, hash tables and all kinds of dynamic structures. A linked list is fully dynamic and exist entirely hidden in memory except for the single starting node. The funny thing is that when building this linked list with the pointer system, one get a list that fully (as far as i can see) adheres to data flow principles (as can be seen in the BD, although it is only the single starting point that flows). Download File:post-4885-1156792100.zip
  19. I'm just wondering if the project file is deleted somehow, will it still be possible to edit the objects (LVOOP)?, or are they/inheretence etc lost forever?
  20. OK, I have converted my Pointer/ref system to LV2OO. I have not tested it performance-vise because i'm not sure if i have done everything correct yet. My experiences are these: It was a somewhat of a pain to make all the classes and all the get/set functions needed for each class, especially when they all are virtually identical. I mean OOP, isn't that about code reuse? It was also a bit painful to stretch my head to think in "LVOOP way" about these actions instead of a simple case statement. Isn't this kind of programming actually called actor oriented (AO) and is more of a functional programming thing, or am i totally lost here?? When it all was finished i noticed a severe limitation (bug?) of the Project Explorer/inheretence functionality. Every inhereted function(vi) need to have the same name, but since they cannot have the same name in the same folder, i had to make separate folders for each and every inhereted vi. When there is no direct relation between the folders in the Project explorer and the real folders, this is *really* confusing and extremely irritating. When that was fixed it worked at first try when looking at the code, and the ease of which things now can be changed, add functionality etc, i have to admit that LV2OO is a major leap in the right direction even though the initial amount of code needed at least doubles for this simple pointer class. The downside is that because the code is "granulated" down to its smallest units, it IS more difficult to get an overall picture of what the code actually does (at least it takes more time), but at the same time this granulation makes it much easier to test the code, and therefore make it work at first try. All in all, i'm impressed so far. I still don't know how LV2OO scale up to be used for general LCOD style, and i am still a bit concerned about performance, but for normal LV2Globals it certainly is a very radical improvement :thumbup: :thumbup: . I have included the code. Download File:post-4885-1156686272.zip
  21. Here is another variant. This is a pure object pointer. It will make a reference-data pair to any LVOOP Object that is sent to it, othervise it is exactly the same as the last one. Download File:post-4885-1156603068.zip
  22. Thats a good question Sorry, but i din't see that at first. I think the answer is that the control and indicator have separate memory allocation rules, different from wires and subroutines. The indicator can have different dimension compared to the control, so a separate buffer for the control is set. I ALLWAYS make sure that i do not change array dimension in subroutines unless that is part of the functionality. I learned that from trial and error and from boards like this. I think your example show the impotrance of this, although *exactly* what is going on inside the compiler is still a bit mystic to me.
  23. Well, after some more thougts i think that when using LV2 style globals and LCOD programming style the reality is that the LV2 global is not just a storage buffer, the LV2 global(s) *is/are* the program. The reason this works is because you can have an abundance of shift registers for all the different data and operate on them in any thinkable manner according to the LCOD function. Adding and deleting data is just a matter of adding and deleting shift registers. With the LV2OO you have to cramp all these data from shift registers into one VI. This will cause at least two problems. Adding data (for instance adding one more array and a few bools that you forgot to start with) becomes a serious task when you have to change maybe several tens of sub classes and their VIs. Another problem is that there just is not enough slots in the connector pane for input and output of data. Besides, when thinking of the LV2 global in terms of LCOD style, since the LV2 global is the program, changing that LV2 global WILL be a serious and error prone task no matter how you look at it. But i dont think it will be more complicated than changing the code in a LV2 global than changing the same code in a child class. It will probably? be more work in LV2OO because you potentially also have to change a multitude of connector panes?. But i have to try this LV2OO first because it looks very interesting . However, i have a feeling that LCOD is such a strong programming style on it's own (completely unbeatable compared with any GOOP when you have lots of data to manage and send around), that a truly strong concept would be to put LVOOP into the frames of LCOD, and not the other way around.
  24. Whenever you change the size of an array, memory need to be allocated/deallocated. Therefore, if the array dim entering the tunnel on one side is different than the dim on the other side, labview creates a buffer. Replace array subset conserve the dim, while build array changes the dim. This has to be so even though the dimension does not really change in your vi, because LV has no way of knowing the the dim in the new data is the same as the dim in the deleted data.
  • Create New...

Important Information

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