Jump to content


Photo
- - - - -

Inplace Typecast possible?


  • Please log in to reply
8 replies to this topic

#1 Götz Becker

Götz Becker

    Very Active

  • Premium Member
  • 136 posts
  • Location:Munich
  • Version:LabVIEW 2011
  • Since:2004

Posted 09 November 2011 - 07:59 PM

Hi,

is there a way to do a typecast e.g. from SGL to I32 inplace, without the buffer allocation?


#2 asbo

asbo

    I have no idea what you're talking about... so:

  • V I Engineering, Inc.
  • 1,273 posts
  • Version:LabVIEW 2011
  • Since:2008

Posted 09 November 2011 - 09:04 PM

Can I ask, what's your concern with the buffer allocation? In case you're operating under the same assumption I was, a buffer allocation is not the same thing as a data copy.

#3 Götz Becker

Götz Becker

    Very Active

  • Premium Member
  • 136 posts
  • Location:Munich
  • Version:LabVIEW 2011
  • Since:2004

Posted 09 November 2011 - 09:34 PM

I was optimizing a tight realtime loop. During my first tries I ignored the buffer shown at the typecast because of the remarks from AQ here in the forum. After hours of tracing the code with various trace user events (I presumed the "scanned variable read" function was the cause of all the "wait on memory" trace entries), it was clear that the cast of a SGL to I32 takes some microseconds (~ 2 us on the used PXIe-8133).
The way the type cast works is actually well documented in the help... too bad I thought I knew it better.

It would be nice if the typecast would only do a buffer allocation if the source and target data type were different sized.


#4 asbo

asbo

    I have no idea what you're talking about... so:

  • V I Engineering, Inc.
  • 1,273 posts
  • Version:LabVIEW 2011
  • Since:2008

Posted 09 November 2011 - 11:33 PM

Maybe this is too obvious of a question, but can you move your typecast out of the loop (either delay it or do it before the loop, based on your circumstances)?

#5 Götz Becker

Götz Becker

    Very Active

  • Premium Member
  • 136 posts
  • Location:Munich
  • Version:LabVIEW 2011
  • Since:2004

Posted 10 November 2011 - 07:04 AM

This is what I actually did for getting rid of the buffer allocation, basically switched from array of I32 to an array of cluster of I32 and SGL as type for the RTFIFO for the interloop communication. Now the typecast is done in a lower priority loop where I can tolerate the timing/jitter induced.

The general question remains... is there a way of an inplace typecast in LV?


#6 GregR

GregR

    More Active

  • NI
  • 47 posts
  • Location:Austin
  • Version:LabVIEW 2011
  • Since:1992

Posted 10 November 2011 - 05:48 PM

*
POPULAR

The typecast node will never use the input buffer for the output. In fact not only will it copy the entire buffer, on Intel processors it will visit each element to put it into big endian format then visit each element to put it back to little endian. If an API requires users to typecast significant amounts of data, I would consider that a deficiency in the API that should be redesigned.

For cases where the array elements are the same size, it would be possible to write a DLL that took both types and swapped the array handles. Be sure to configure both parameters as pointer to array handle then swap the handles.

#7 ned

ned

    Extremely Active

  • Members
  • PipPipPipPip
  • 392 posts
  • Location:Menlo Park, CA
  • Version:LabVIEW 2009
  • Since:1999

Posted 10 November 2011 - 06:12 PM

The typecast node will never use the input buffer for the output. In fact not only will it copy the entire buffer, on Intel processors it will visit each element to put it into big endian format then visit each element to put it back to little endian. If an API requires users to typecast significant amounts of data, I would consider that a deficiency in the API that should be redesigned.

Thank you for that information, although it means in retrospect I've written some pretty inefficient code (for example I've often used Type Cast in place of Array to Cluster when I have a large cluster that I modify frequently and I don't want to keep updating the number of items). The use of C-style hints over the terminals makes it look like it's equivalent to a cast in C, where there is, of course, no memory penalty.

#8 Götz Becker

Götz Becker

    Very Active

  • Premium Member
  • 136 posts
  • Location:Munich
  • Version:LabVIEW 2011
  • Since:2004

Posted 11 November 2011 - 08:03 PM

I opened a thread in the idea exchange for this:

http://forums.ni.com...t/idi-p/1771970


#9 rolfk

rolfk

    LabVIEW Aficionado

  • Premium Member
  • 2,045 posts
  • Location:Netherlands
  • Version:LabVIEW 2011
  • Since:1992

Posted 12 June 2012 - 06:33 PM

Thank you for that information, although it means in retrospect I've written some pretty inefficient code (for example I've often used Type Cast in place of Array to Cluster when I have a large cluster that I modify frequently and I don't want to keep updating the number of items). The use of C-style hints over the terminals makes it look like it's equivalent to a cast in C, where there is, of course, no memory penalty.


No C does not have any memory penalty but if you cast an int32 into a 64 bit pointer and ignore the warning and then try to access it as pointer, you crash. :yes:
LabVIEW is about 3 level higher in terms of high level language than C. It has among other things a strong data type system, a rather effective automatic memory management, no need to worry about allocating array buffers before you can use them and releasing them afterwards, and virtually no possibility to make it crash (if you don't work on interfacing it to external code) and quite a few other things. This comes sometimes at some cost, such as needing to make sure the buffer is allocated. Also the nature of LabVIEW datatypes seperates into two very different types. Those that are represented as handles (strings and arrays) and those that aren't. There is no way LabVIEW could "typecast" between these two fundamental types without creating a true data copy. And even if you typecast between arrays, such as typecasting a string into an array of 32 bit integers, it can't just do so, since the 32 bit integer array needs to have a byte length of a multiple of the element size, so if your input string (byte array) length is not fully dividable by four it will need to create a new buffer anyhow. Currently it does so in all cases, as that makes the code simpler and saves an extra check on the actual fitness of the input array size in the case where both inputs and outputs are arrays. It could of course go and check for the possibility of inlining the Typecast but if your wire happens to run to any other function that wants to use the string or array inline too, it needs to create a copy anyhow.

All in all this smartness will add a lot of code to the Typecast function, for a benefit that is only in special cases achievable.