Random Ramblings on LabVIEW Design

Community Browser
Labels
cancel
Showing results for 
Search instead for 
Did you mean: 
swatts
5509 Views
30 Comments

Hello my lovelies

This blog has not been nearly ranty enough lately, so.................

There's a lot of proscriptive recommendations in the LabVIEW world and some of them we struggle to understand, so keeping with our foolish nature let's have a closer look at them.

Over-use of Case Statements is Bad!

This is often trotted out and  WE JUST DON'T GET IT!

A case structure in LabVIEW is equivalent to a switch statement in C++ or Java, It's interesting to see if there are design restrictions on the number of branches handled in a single switch statement in these languages. A search didn't show much, this indicates that it's not a big issue in these languages. In fact the only issue was that in text based languages the statement becomes a pain to read through. Um not an issue with LabVIEW (although better filtering/navigation of the case structure would be a massive improvement).

We've even seen a company coding standard that limited the number of cases in a statement. Why on earth would you want to constrain your designs in such a way??

Local Variables are evil!

Rather than blandly inhibit their use wouldn't it be better to describe the situations where badly placed local variable cause issues (the "expert" says that Local Variables are bad lets just spread the meme without thinking about it). If you have a massive block diagram spanning a lot of LabVIEW dataflow time and you bung local variables into the free space you will probably get dataflow issues. Methinks the issue is not understanding dataflow rather than using local variables.

Our advice is to use Local Variables in bounded LabVIEW structures doing one thing only (short and sharp). So Event Structures, States and Queue driven case structures work fine in our book. That way you will read a valid local value, the diagram will be nice, clear and clean and if you have named your variables correctly it will help document your diagram too. 

So what is more difficult to understand a clearly labeled and named case structure with bounded local variables acting on this data or a load of complex logic, data wires through shift registers or references. (ducks out of way of the incoming flames).

Oooh the concept of diagrams spanning dataflow time!!!, maybe there is a seed of an idea here related to the physical aspects of a system.

Global Variables are more evil!

Again the proscriptive statements around global variables are "Global Variables are bad, they cause race conditions". This annoys me because it takes a pretty standard software design issue and makes it LabVIEWesque. It would be better to write it "Global Variables can cause problems because shared data is tight-coupling and this will cause unpredictable behavior". We've said it before but once again: race conditions are just one symptom of poor data coupling. We find global variables very useful, but we make them private members of an LVLIB and use a public interface to control access to the data if required (ideally it should stay in the bounds of the LVLIB). The real truth is that in a well designed system you shouldn't need global access to data.

"Two routines are global-data coupled if they make use of the same global data. This is also called common coupling or global coupling. If use of the data is read-only, the practice is tolerable. Generally, however, global-data coupling is undesirable because the connection between routines is neither intimate nor visible. The connection is so easy to miss that you could refer to it as information hiding's evil cousin......information losing"

Steve McConnell - Code Complete

Stacked Sequence Structures are like the goto statement in BASIC

no they are not!

The worst crime a stacked sequence structure is guilty of is obscuring some of your code. It's equivalent to using 5 pages rather than 1 long page, and actually the true crime is writing code that needs compressing in such a cumbersome fashion. It's never caused us a single issue with understanding the block diagram. Unlike goto statements which are a complete structural nightmare in text based languages.

Our coding standards do not proscribe tools or techniques but mostly concentrate on readability and simplicity.

On another note..

Function Points.....

We think this is an important exercise and we're going to ignore the lack of reaction to the article and plough on regardless with a manual trawl through an SSDC project and try and finalise a method for reverse engineering the Function Points of a project. This will include some VI Metrics, but we're trying to pull out just logical complexity. We will then try and automate the process. We've just got to do the hard miles first.

Lots of Love

Steve and Jon

ssdc-logoXparent.png

swatts
7755 Views
2 Comments

Hello Lovelies

We have been reading a lot of discussion recently about LabVIEW performance and scalability and this has become increasingly interesting to us because we don't have any real issues with it. Is it the technique/method or the project that is making the difference here?

Well, before we can really evaluate techniques and methods we need to be a bit more scientific about judging and comparing project complexity. If for example you are using 15 classes, 400 VIs etc to print "Hello World" it should come as no great surprise that LabVIEW grunts a bit when you actually throw a real-life project at it.

Function Point Analysis is a method of breaking down a project down into similar sized lumps, as an estimation tool these lumps are generally based on an approximate effort to do a task. In this discussion we want to pull it a little bit away from just being an estimation tool and use it as a baseline for our complexity metrics.

So project xxxx would have 350 FPs and if we use 500 VIs to solve the problem rather than 5000 will LabVIEW perform better. If this is the case (and without doing this work any discussion is fairly meaningless currently), should we then modify our techniques to better accommodate LabVIEW. At the very least we would have a tool the would help us predict if we're going to run into trouble.

So here are some examples of a single Function Point, this could be argued as being too fine a grain, but we have to start somewhere.

1 Hardware Action (e.g. DMM Initialise)

1 Database Query

1 File Action (save or load)

1 User Interface Update

1 User Event

1 Report Action

1 State - transition (counting the transitions may give a better number than counting the states, but I'm undecided about this)

1 Communication message (via Queue or any other transport mechanism)

1 Logical Decision

Distributed systems should be regarded as separate projects.

The point of the exercise is to come to a consensus regarding a projects complexity so expect a bit of averaging out here and there (for example an INSERT SQL statement is more tricky than a SELECT but it should even out in the end)

So a question to you clever people is...

Can you think of any others and do you think this worth pursuing?

The next stage will be to assign these FPs to existing projects and do some comparisons. Perhaps User Groups could help here.

Lots of Love

Steve

swatts
3854 Views
9 Comments

Hello Lovelies,

If you've read some of our articles you'll be aware of our thoughts on Codes Smells and Anti-patterns. We think the term enbugging is a very elegant addition to this lexicon.

This article is based on the article by the Pragmatic Programmers.

A bug creeps into your code, it's not your fault it's just a bug, a gremlin, a random happenstance....

Or that's what we tell our bosses.

That's the easy way out, a bug is a mistake, it's a mistake in understanding, a bad design decision, an over-complication. The only people who don't make mistakes are not doing anything. We're very suspicious of people who don't make mistakes!

Sometimes you can have a day when you seem to actively putting bugs into the code. Welcome to the world of enbugging.

It's usually takes some setting up to have a really good enbugging session, decisions that are made days before cumulate into a world of pain. Removing 1 bug will generate 2 more. It's a recipe for stress and worry.

The techniques in the article for reducing enbugging talk about encapsulation and information hiding, writing "shy code".

In OOP an object responds to messages and these messages should follow the rule "Tell, Don't Ask". In LCOD we call our enumerated type a command and not a query. We are telling our object to do something, it may respond with some data or it may not. It's internal data is private.

Also minimize how much our objects chat to each other, keeping the data shared by our objects to a minimum (coupling) also makes it more difficult to put bugs in. Generally less shared data equals more predictable code, easier testing and less bugs.

Bugs like to hide!, you can help the enbugging process by giving them lots of places to hide in. Large block diagrams, making lots of decisions are a wonderful, fertile bug garden.

Small Testable VIs are more akin to a desert.

A cluttered block diagram is also a wonderful place to hide bugs. A clean, easy to understand block diagram makes enbugging far harder.

If your bag is dynamic loading make the dynamically loaded VI cohesive enough to be tested.

In fact a lack of testability is a wonderful way to grow bugs. If testing is hard you need to be pretty damn sure of yourself!

Bugs can easily placed in arrays, logic, maths and my own particular nemesis dates.

So where else is the best place for bugs to lurk?

Lots of love

Steve Watts and Jon Conway