Jump to content

LVOOP & the JIT compiler


Recommended Posts

One of the benefits of using interfaces (or abstract classes) in code packages with text languages is that as long as you don't mess with the interface you won't have to recompile the code that depends on that package. Labview's just-in-time compiler allows us to ignore recompiles; however, hiding them under the covers also prevents me from learning how much JIT compiling impacts performance and exactly what circumstances require a recompile. In particular, the scenario I'm imagining is one with a large, multi-package reusable code base where there are various dependencies (inheritance, composition, references, etc.) between packages and the packages are released/updated on different schedules. I've run a few very simple tests, but I can't think of any way to test this at a large scale without actually building a a bunch of packages.

Along these lines, I have a few questions:

  1. What's the best way to minimize the time spent doing JIT recompiles when starting an application that uses those packages?
  2. Do we know which types of dependencies are 'clean' and which are 'dirty?' For example, package A can depend on package B, but if the only interaction they have is through a string-based messages it's unlikely changing B will trigger a recompile in A. On the other hand, if package A inherits from a class in package B, changes in B are more likely to require a recompile in A. What if A contains B as data? What if A contains a reference to B as data? What if A member vis have B constants on the block diagram? What if A member vis use B member vis on their block diagram?
  3. Does JIT compiling have a practical impact on load times or am I splitting hairs?

Dave

Edited by Daklu
Link to comment

The LabVIEW runtime engine doesn't do any compiling whatsoever, so if you have an interface parent class and a bunch of implementation child classes, and all of those are compiled and saved, then you don't have to worry about the runtime engine trying to recompile them.

There's something going on in the IDE I don't understand. Suppose I have a Base class, a Child class, a composite of the Base class, and a composite of the Child class. If I make a change in the base class that requires a recompile, such as adding a private data member, Base class and Child class objects on block diagrams are dimmed. I've always thought this essentially means Labview can't execute this code until that file is saved (or has its changes applied.) If that's not the case, what is the significance of dimmed objects? Dimming the child class suggests a tighter coupling between the Base and the Child than between the Base and the Composite Base.

post-7603-124967720247_thumb.png

The reason for the question is I have packages that will expose abstract classes which other packages will use to derive their own classes and objects. I can save a lot of duplicate code if I include some functionality and private data in the abstract class, but I don't want get bogged down in package-dependent recompiles when I change its private functionality. (This applies to both the runtime engine and the IDE.) I was considering making the exposed base classes purely abstract just to make sure I wouldn't have to change it, but it sounds like there's nothing to gain by doing so. Correct?

Link to comment
  • 2 weeks later...

Thanks for the detailed responses Adam. Letting your answers percolate for a few weeks helped clarify thing for me, but of course also raised a few new questions. To put the questions in context, I'm currently in the early phases of designing internal frameworks that will be distributed to other Labview developers for creating applications to test our devices. I'm planning on deploying the components as multiple OpenG packages and these questions come up when I consider updating a package without having the application source code loaded into memory. Also, since these are under source control I'd prefer not to have to checkout and resave a bunch of vis when updating a package.

1. In the .lvclass file there is a property named "NI.LVClass.FlattenedPrivateDataCTL." What information is actually stored in Composite (Base).lvclass when a Base.lvclass object is included as private data? Given that Composite (Base).lvclass doesn't need to be resaved when Base.lvclass changes, it implies that Composite (Base).lvclass is in fact storing a link to Base.lvclass rather than a representation of the object (and data) itself. What happens if I use a Base object with non-default data as private data in Composite (Base).lvclass? Composite (Base).lvclass needs to maintain a representation of the data, right? Suppose I go back later and delete a private data member from Base.lvclass that is no longer needed. How does Composite (Base).lvclass handle this?

2. If my package exposes a typedeffed cluster for clients to use, what changes can I make to the typedef in the package without breaking (either broken run arrow or unexpected runtime behavior) client code? Obviously deleting items could break clients. What about renaming items? Reordering? Renaming and reordering?

3. How does the answer to Q2 change with respect to enums rather than clusters? (My gut is that renaming or adding would be okay but reordering would be bad.)

JIT refers to compiling right before executing starting from a partially compiled binary. For instance, .Net code compiles to a bytecode format (not directly to machine code), but instead of a bytecode interpreter they compile the bytecode right before you run it into machine code optimized for your processor.

I was using 'JIT' to refer to the background compiling that happens in the Labview dev environment. What do you call that process? Precompiling? A level 1 compiler? On large projects I've seen a several second delay between hitting the run button and having the application actually start, so I don't think it compiles directly to machine code.

Link to comment
I was using 'JIT' to refer to the background compiling that happens in the Labview dev environment. What do you call that process? Precompiling? A level 1 compiler? On large projects I've seen a several second delay between hitting the run button and having the application actually start, so I don't think it compiles directly to machine code.
That's just plain old compiling. And that's what we call it. :-) The fact that you as user don't have to explicitly invoke it is a service on our part, but the compilation happens before you run, which is exactly when it happens in every other compiled programming language.
Link to comment

That's just plain old compiling. And that's what we call it. :-)

So the background compiler generates machine code on the fly in a single step and stores it in memory? Or does it compile down to function calls for the runtime engine to translate into os specific commands?

The fact that you as user don't have to explicitly invoke it is a service on our part

Ohhhhh, so that's why Labivew is so expensive. wink.gif (I'll gladly use a compile button if it knocks a few thousand dollars off the price.)

Link to comment

It's been said many times but I'll repeat it again... it sure is nice to have NI insiders responding to questions and comments on public forums. It leads to a level of understanding that otherwise would take years to achieve. Thanks.

Magic. Actually, the .lvclass file also contains a history of edits you've made so that it can automatically mutate any old data on load. It's mostly transparent to the developer, and it makes mixing versions of classes much easier than in other languages. The only time you'll run into problems is if you have an older version of the class in memory and then later load some VIs that have data from a later version. I'm not sure exactly what happens in that case, but I think it would fail to load the VI.

I like magic. So much of the world can be explained with it. biggrin.gif

I don't think I've run into this problem yet, but I can see how it might happen when deploying reusable code packages to an application subdirectory instead of a common shared directory.

There are few if any changes you can make to a typedef that won't break your clients.

Got it. Typedefs within a package = good; typedefs across package boundaries = bad. (Unless you are 100%-for-sure-guaranteeing-cross-my-heart-hope-to-die-swear-on-my-mother's-grave that it won't change later.)

With enums I think you can add to the end of the enum, but removing or renaming an existing item will break the clients. If you really need to do something that would break a client...

I've been more concerned with a developer accidentally breaking a client with a future change. The specific example I was thinking of with the question of enums was the factory pattern example with Orange and Blue classes. Using an enum as the class selector makes it easier for the developer using the factory, but it also seems like a prime spot for bugs to appear. LV developers are used to being able to change enums and having the changes propogate through all the code.

Good unit testing is certainly needed but I'd prefer to prevent the errors from making it into the code in the first place. I'm tempted to limit cross-package data to natural data types (numbers, strings, bools, etc.) and objects. Hopefully that would remove the temptation to make "easy" changes. I'm not convinced the added developer overhead in maintaining string processing is worth it in the long run though.

Aristos explained this decently. We do compile directly to machine code...

If you don't mind my asking, how do you manage to allow us to step through the code if it's primarily machine code? VB6 was interpreted so I can understand how they managed that. C#/VB.NET are compiled to IL so I can see how they could do it there too. There's a big gap in my knowledge between high level programming languages (LV, C#, VB) and my low level hardware knowledge (68HC11 & AVR microcontrollers) so if it's too much to explain don't worry about it.

The one caveat to that is that sometimes changing a subVI causes the callers to need to recompile, so you might get a prompt to save a VI you never changed directly. That's because we recompiled that VI to adapt to the changes in its subVI(s), and we want to save that new code so you don't have to recompile again next time you load.

And the changes that trigger that might be...?

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

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