Jump to content

bsvingen

Members
  • Posts

    279
  • Joined

  • Last visited

Everything posted by bsvingen

  1. I see that you are using LV 8.0.1 When building a DLL in the project builder you have full control over all data. Make sure you choose C calling. I tried your filter, and my header file automatically made by the project bulder looks like (the default, i didn't do any changes): #include "extcode.h"#pragma pack(push)#pragma pack(1)#ifdef __cplusplusextern "C" {#endifvoid __cdecl ButterWorthFilter1(double samplingFreqFs, double lowCutoffFreqFl, double Input[], double Order, double Output[], long len, long len2);long __cdecl LVDLLStatus(char *errStr, int errStrLen, void *module);#ifdef __cplusplus} // extern "C"#endif#pragma pack(pop) here "len2" is acosiated with Output and len with Input. So they are just ordinary arrays.
  2. Here is an example of improvements in execution speed with inlining. In general inlining is useful when you have lots of small numerical formulas that have to be executed often, for instance when you have two or more arrays and have to do some more or less complex operations on array element basis. This is typical for most data analysis applications. With inline functions the code maintains the modularity (readability) while all the overhead associated with sub VI calls disapears completely. The increase in execution speed can be dramatic for some applications (several hundred percent), while for others no practical increase is seen. When inlining, the the code becomes very unreadable, so it is only usefull to gain execution speed when the code or sub-parts of the code is finished. A copy of the un-inlined code must therefore be stored for later modifications. Here is the execution speed before inlining. The inline sub VI has the same execution speed as an ordinary sub vi (they are identical ). The one stored/compiled as subroutine performs more than twice as good as the other two. After inlining, the picture is different. Now the inlined code perform almost twice as good as the subroutine, and about 350% better than an ordinary sub VI. This is the effect of one single inline function. For more complicated formulas where the code needs to be broken down into several sub VIs, the improvement will be even more. (Actually the equations in this example are so simple that faster execution speed is obtained by feeding the arrays directly, but that is beside the point and only shows that too simple examples are not allways the best examples ) Download File:post-4885-1150670897.zip
  3. Well, after discovering that an inline method already exists by default in LV (scripting), and with thanks to Jim Kring for pointing me to the traverse tool in LV8, the inline tool became much smaller and simpler. Basicly what it does is to inline all sub VIs with __inline in their names (double underscore in front of inline. I don't know if this is the best option, but it works). It uses the NI tool to traverse the diagrams, while the main loop will recurssively loop through all sub VIs. inline VIs can therefore be inside other inline VIs, and the tool will just go through the complete hierarchy. It will not touch any locked files. I could have added some statistics etc, but i have no use for that myself, so you have to add that if it is needed/wanted. Download File:post-4885-1150641218.zip
  4. I was cleaning up my inline code and just by curiosity i was looking at the invoke node methods for sub VIs. What do i find ? Yes, an inline method. It has a "makespace" and the possibility to wrap the code in a sequence frame. I tested it, just replaced it with my inline tool, and - it works. I have not tested it thoroughly, so i do not know the requirements etc. Well, at least there should be no problem to write a nice app that inlines VIs :thumbup:
  5. I have seen some hints here and there that the next version of LV will have GOOP. I therefore wonder if someone here situated closer to NI (both geographically and othervise) have some more detailes (i am sure there is...) : Will GOOP be built in from the ground, or will it be just an addon? (crucial regarding performance. Looking forward to testing the performance penalty with GOOP. If done well the penalty should not be more than 10-20% compared with "ordinary" coding) Will it be possible to use property nodes and invoke nodes on selv-made objects? (crucial regarding practical usability) Will it have inheretence?
  6. I have had this in the back of my head for a day or two now, and i see that alot of testing for different posibilities have to be done for such a thing to work in all cases. * Default unused terminals must be exchanged with constants. * Unused exit terminals must be deleted at expansion point. * (void) terminals must be handled correctly * The application has to stop on errors like: * internal terminals (cannot be allowed for inlined vis) * graphs, charts etc cannot be allowed * any reference to the inline sub vi cannot be allowed (although i'm not sure how this should/can be checked in a consistent manner) * The inline sub vi cannot rely on special vi options, like default error handling, first call etc On the other hand, i'm not sure at all if all this checking is neccesary. I believe the persons who would use inlining in the first place, would also be very consience about these constraints. ?? I know i will Then the code needs to be recoded properly, and travirsible through all structures and also all sub vis. I think i will use the loop method for recursion that i saw an example of here somewhere, instead of the call by ref method. The loop method is probably much more efficient and certainly much easier to understand But i'm not quite sure how this willl work through layers of sub vis, since there are some basic things about scripting i do not understand (do the vi's have to be opened in a special way? etc).
  7. I use the LCOD principle in a very large application, and i use dqGOOP within the "LCODs" to pass data and references between elements at init (i could have used an ordinary queue without the goop around it, so the main reason was actually to be sure that i only had thin green wires instead of those ugly queue wires with different internals At init stage there are no speed considerations either so dqGOOP was the way to go). Anyway, from a practical point of view, i still cant see the main benefit of "real" GOOP in LV when we have LCOD and named queues. The named queues take care of everything at initialization, enabling you to route data and references to "executables" very efficiently to wherever you want so that everything is sorted out before execution, and can be changed also during execution. The LCOD principle assures at least the same scalability as GOOP, i would say with more scalability, since all this can be done without the need for refs. Those refs in all GOOPS i have seen are managable if you only have max 5-10 objects or so, but with 50-100-200++ objects of different sorts, then the refs makes the whole thing impossible. In my opinion GOOP (as implemented in the current available packages) is scalable only in terms of expanding the application around those very few objects you may have in the first place, not in terms of expanding the set of objects within that application. I guess you can use queues to pass those refs around instead of ref-wires, but then you end up being terrible close to the starting point of LCOD and queues. But, as other people have said, the right technique for the right job is the most importent consideration, and the more tecniques, the better.
  8. 2D arrays in C are not "ordinary" 2D arrays, but an array of pointers to arrays (pointers to pointers to whatever). Labview stores 2D arrays as 1D contiguous block of memory, or as a 1D array. The only difference between 2D and 1D array in labview is an extra long int that hold the second dimension.
  9. My first scripting applications Considering that this is my first scripting application in LV - ever, this program must be considered a proof of concept of inlining VIs, and nothing more. Most of the time was spent on figuring out this scripting (i guess i know 5-10 % of it now ), while the application itself was straight forward once i found out how to do it. I used the alternating color vi found on this board as a starting point. I also wanted to do recursion to traverse through all the possible loops and structures, but at 2 in the morning my head just refused to cooperate with the nightmarish logics of recursion :laugh: The way it works is to figure out the terminals of the sub vi and the closest connecting terminal on the main vi. The refs to the main vi terminals is then stored in a cluster array with the name of the sub vi terminal as the first element in the cluster. This array is then sorted. Then the whole diagram of the sub vi is copied to the main vi and all the new control terminals is stored in a cluster array with the names as the first cluster element. This array is also sorted. These two arrays now have a 1 to 1 relation for the "closest" terminal in the main vi and the copied control terminals from the sub vi, so i then wire these to together. Then i just delete the copied control terminals and the sub vi, clean up the wires, and the sub vi is inlined into the main vi. One thing i figured out with this, was that void connector pane terminals also is considered terminals in LV, but an error is set once i try to read the wires. This means that the sub vi made for inlining cannot have any void connector pane terminals (unless the error is cleared). The vi and a small test is included. I guess it works only for LV7.1.x :beer: Edit: It also works for LV8 with a small modification. Make a folder out of the llb and browse for the full vi path for the main.vi in the path window. (The strange "NI system sub vi" that i do not know what does, but seems to be needed, needs the full path in LV8, not just the name) Download File:post-4885-1150247564.llb
  10. Exactly, this is my experience as well But then you start to become more and more irritating when it each dataset takes 20 minutes instead of 5 :beer:
  11. I think some of you are missing the point here To use applications that do not require fast execution as examples of why fast execution is not needed is completely irrelevant. Not everybody is working on non critical systems where the processor is basicly idling 99% no matter how you bog down the code. It is those applications that need fast execution, or where fast execution improves overall performance i am talking about. Of cource i can use a DLL, code the whole thing in C or whatever, but that is also completely irrelevant and only serves to dodge away from the issue. For instance, can anyone give me a good reason why a simple x*sin(t) + y*cos(x) takes almost twice as long to calculate in compiled G than compiled C? An answer like "99% of the time there is no need..." just is not good enough, 1 % for you may be 70% for me. There is no need for an "highly optimized" compiler of any kind to do this, any compiler available will compile faster code than G since these functions are standard functions that are optimized several decades ago in terms of algorithms. I think much of the answer lies in the process of function calls instead of inlining which requires overhead and buffer alocations where clearly neither the overhead or the buffers are needed to complete the functions. From the manuals i can read that the data flow paradign creates (sometimes unessecary) buffers, and indeed manual optimizing of buffer allocations can speed up the code when working with arrays in particular. But when examining another function, z = sqrt(x*x + y*y), in G and a text based language it becomes clear that it is not the dataflow paradigm that is the cause of the buffer allocations, it is function calling itself and the simple fact that the G compiler does not do any optimization even though the the code is contained in a sub VI, it simply "goes by the book". x*x + y*y will be a parallel execution in G and since they call the *function* x^2 (in LV8) or standard multiplication, it creates two buffers, where clearly one buffer is enough to complete the code, namely the buffer for z.
  12. I have noticed that if you have different DLLs with the same name in different folders and change between them, Labview does not always change to the correct one. It get stucked with the one it find when you load the vi, even though you manually change to another one. It has happened to me several times (in LV7-7.1), but i'm not sure if it always happends. Another ting is that you should make the prototype in LV (the "make C code" or something in the DLL call in LV), then you are 100% sure to use correct types.
  13. I can add that at initialization the "This VI" ref for each element or reentrant vi (also new in LV8) is stored in a named notifier. This notifier is later used in a main user interface to open the appropriate reentrant instance (when i build executable stand alone simulators). In the main user interface the named notifier is associated with custom made boolean switches that represent and looks like the physical object (for instance a pump), so that when the user click on the pump picture, the front panel for that particular instance of the pump sub vi is opened. The "This VI" ref and reentrant vis with front panels that can be opened looks very object orientet to me. Does anyone know if this is a gradual tramsition to natively implemented OOP in newer version of LV?
  14. I have used it in a different content. My vis are already running, and i use the FP.Open method or double click them in the block diagram to show the front panel as a user interface for particular instances of the vi (show graphs, input and so on for the elements in a simulation package). It is not only possible to open the FP, it is also possible to debug the instance, just like any normal vi. Basicly it has enabled me to make "objects" with working front panels. Previously i made these "objects" as distinct vis on the harddisk to be able to see front panels. This worked OK, but it was not possible to make a menu system in the palette for these objects (there would be 70 different objects of the same type but with different name, XXX 01.vi and so on). It was therefore easier to drag them into the diagram directly from the folders. Now it is possible to make a real palette, a toolset with vis that have interactive front panels. With this toolset i run the simulation directly in the block diagram and have full interactive possibilities simply by double clicking on them while running. It is also much easier to build systems when you can use click copy and drag. The Labview graphical programming environment (the block diagram) and these reentrant sub vis will together make a full featured simulation package for design and engineering, just as good as anything else. I can also make stand alone executables (a real process simulator that also include measurements from the real system) using the exact same block diagram. Then i must use the FP.Open method and build a user interface (wich is needed for simulators in any case).
  15. Certainly not my own icon editor, and i'm sure it is old news, but for those who don't know there is another icon editor with LV8 in LabVIEW 8.0\applibs\iconeditor\iconedit.exe Some of the nice features are: * Antialiased text (text looks incredible much better, especially small text). * All the fonts in LV are available. * Very good selection tool. * Ability to make circles and ovals I think it is a part of the project builder, because i saw it when i first made an executable in LV8 It does not make LV icons, but you can copy and paste the whole icon, or just parts directly into the LV icon editor.
  16. You are probably right. Each sub vi marked as "inline" would have to be replaced with the equivalent inline code. But if those inline sub vis could be put into a frame and shrunked as mentioned earlier, then i guess it also would be possible to reverse the process? It is however difficult to see that this can be done without ending up with a duplicate set of files, and maybe the end result would just be too messy to weigh up for the increase in speed for anyting but a final executable where the diagram is irrelevant. I think the increase in speed could be large because a typical structured labview program has several layers of sub vis calling other sub vis and where the sub vis in the lowest hierarchy doesn't really do all that much, sometimes only some kind of wrappers around very simple primitives. The spline interpolation backage in LV8 is a typical example of this.
  17. I agree, but what is confusing here is that there exist a pow(x,y) in the formula node and and an equivalent diagram function. There also exist (in LV8) a square diagram function. It is therefore easy to believe that since pow(x,y)_formula node = pow(x,y)_diagram, then x**2_formula node = x**2_diagram, but this is not the case. There exist no square formula node function, only two ways of writing the power function.
  18. This is interesting and very strange. I made another simple test case that calculates z=sqrt(x^2 + y^2) when the variables are in an array and the output is an array. Here the strange thing happened that when doing this "inline" with diagram and calling the same diagram as a sub vi, there seems to be abselutely no penalty for the sub vi call, even when the sub vi is a "normal" one. Another thing to note is that calculating x^2 as x*x is approx 5 times faster than using x**2 in a formula node. This is for LV7.1.1 Download File:post-4885-1149120243.zip
  19. I downloaded the "process spawning" article. Great article with lots of useful stuff. However, it needs updating since one thing in there is plain wrong. It says that This is wrong, at least for LV8. I am doing this all the time in my application with front panels for each instance of the reentrant vi. There is also an example in the example folder that shows this feature.
  20. If you make it reentrant, you can simply place it at three different places in the main vi. Just make sure that all the sub vis to the reentrant vis can safely be run in parallel. Any non-reentrant sub vis with shift registers will cause problems. The most flexible method is to make them reentrant and call them by reference (call by reference node). This way you can call three (or more) instances and use those instances wherever you want, and as often as you want.
  21. Seems like floating point is a strange beast to optimize. It is very strange that your FORTRAN dll is slower than the C dll, as they are identical on my PC. My results from your file is in the attachment. Right now i'm using my laptob which is a Dell with a dual Centrino, and it could very well be that one of them (or borth) optimizes for dual cores, or/and for pentium (instead of AMD) etc, but this is only guessing since i have only downloaded them and compiled the code without looking any further into the optimization switches other than put them on "optimization". Basically the C and FORTRAN DLLs are 60 ms while the others are about 90 ms on my system running LV8.0.1 It therefore looks like LV8.2 is much faster. I will try to use the sqr function for cos in the dlls, and see if that will speed up things. Edit: I tried the sqrt function in the C code, but it still was 60 ms, no change that I could see from the graphs.
  22. Strange. Seems like Salford Fortran need some kind of run-time library, very odd for this simple code. I found the salflibc.dll in a "redist" folder in the salford installation folder. Here it is. or not?. The board complains and sends a message that it will not accept i file "with that file extension". I zipped the file, and you need to unzip it along with the others i guess. If it complains about more i think you can install the Salford FORTRAN package or just comment out the call to those dlls, since the c-dlls are almost exactly the same execution speed. The salford fortran is freely downloadable from http://www.silverfrost.com/32/ftn95/ftn95_...nal_edition.asp Download File:post-4885-1148773381.zip
  23. Here is a 7.1.1 version. There is no NI sub vi in this since this is only available for 8.0 Download File:post-4885-1148747671.zip
  24. These simple tests also show the importance of inlining small functions with regard to execution speed. While the basic execution speed in labview is a factor 1.6 compared with C or Fortran (1.4 with formula nodes with no array indexing), it will be practically impossible to maintain that speed in a readable and reasonable maintainable labview application. A factor of 3-4 is probably more representative. A simple inline construct would solve most of this.
  25. Hello The speed of doing floating point operations is important to my application, but how optimize this is in G? I have therefore made a small test program that tests several different methods to see which is fastest. The tests consist of doing 2D vertex rotations of the form: x' = x*cos(theta) + y*sin(theta) y' = -x*sin(theta) + y*cos(theta) The different methods consist of: The included NI sub vi (LV8), an ordinary sub vi, an ordinary sub vi flagged as subroutine, call by refrence sub vi, "inlining" the diagram without any function call, using formula node with arrays, using formula node without arrays, DLL made in C direct call, DLL made in C that takes whole arrays and the same DLLs made in FORTRAN. I also tried a MathScript node, but thas was several thousand times slower than the others so i just removed it alltogeher. Some of the results are very obvious but some are very surprising (to me at least). The one with the diagram "inlined" (directly in the main vi) is set to 100 % while the other are percentages from that one (smaller is better). NI built in sub vi subroutine reference "inline" FormulaN 1 FormulaN 2 DLL C DLL C Arr DLL F95 DLL F95 Arr546 205 123 508 100 177 91 177 64 179 64 In general a G diagram takes 30-40% longer to execute that C or fortran (this i knew), but very surprisingly the formula node is faster than the diagram (10 % faster). However when arrays are put into the diagram (FormulaN 1) it slows down, and it seems to me that it is directly proportional to the amount of array indexing that is done.Using a subroutine is only about 25% slower than a direct diagram, however it already takes twice the time of C/FORTRAN.Using an ordinary sub vi takes twice the time of "inlining" the diagram and the speed of execution is now 3 times longer than C/FORTRAN.Using a call by reference node really bogs things down by a factor of 5 compared with "inline" diagram and a factor 8 compared with C/FORTRAN.Finally the included vi from NI is dead slow, it is in fact very hard to bult a simple routine like this that executes that slow (but i explain a bit more later).Direct call to DLLs is slower than "inlining" the code for this simple routine, but it is still faster than using an ordinary sub vi, and this is very strange. This means that overhead associated with calling a DLL is less than the overhead associated with calling a sub vi, why? The included vi from NI is in fact calling a DLL, so why is it so slow? The reason is that it is calling a DLL that obviously is optimized to take millions of vertices and rotate then the same angle (for instance when rotating a picture). Using it with different angles each time therefor consist in transforming the doubles to an array of one double and do the same for the output and using a routine that is optimized for something totally different then what you are trying to do. Used as it should be used with millions of vertices and the same angle it is extremely efficient, but when used for different angles it is unbelievable inefficient. One can only wonder why NI didnt take the extra 5 min to code this instance of the polymorfic vi using ordinary methods. For the DLLs i have use lcc C compiler and Salford FORTRAN 95, they are both free for non comercial use. I downloaded the FORTRAN compiler today, and was extremely impresses with the ease of making DLLs. It was just a matter of writing an ordinary subroutine and compile and link (I used ordinary F77 code as i have no idea of how to write F95 code ). All the hieryglyphic things associated with DLLs are completely hidden from the user. Anyway, these tests indicates that the fastest possible G coding is to use formula nodes, but do the indexing of any arrays outside the node. This will be faster than any other method in labview. Earlier, my impression was that formula nodes were slow, but that was probably because i did alot of indexing of arrays inside. For pure speed a DLL is the way to go, and with the ease this can be done in Salford, hmmm. The program is included in a zip file. Just unzip and run the "Test 2D Rotate.vi". Only LV8. Download File:post-4885-1148575817.zip
×
×
  • Create New...

Important Information

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