From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to get 16-byte aligned arrays in LabVIEW

Hi,

 

I'm working on a high performance application and we are hitting the limits of LabVIEW. I'm looking to use C for high performance kernels and use LabVIEW to orchestrate those.

 

As part of that I want to use AVX instructions which are more efficient if you can get data aligned on 16 byte boundaries however LabVIEW is aligned on 8 byte boundaries in 64 bit (based on clusters in http://zone.ni.com/reference/en-XX/help/371361P-01/lvconcepts/how_labview_stores_data_in_memory/. It says arrays are as well but doesn't say to what boundary).

 

So are there any tricks where I can generate an aligned array (to 16 bytes) that I can use in C and LabVIEW? I know I could allocate it in C and pass a pointer but it would be nice if I wasn't forced to use C everywhere.

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
Message 1 of 5
(2,566 Views)

You could try to get you're own DS pointer in LabVIEW. Add padding bytes to the size, and then copy the data to the pointer + padded offset. Then pass the DS pointer + offset to the dll? Or of course pass the pointer so you can get the array size, and calculate the padded offset.

 

Not sure if that is better then getting a pointer from C... At least the memory management will be done by LV.

 

 

Message 2 of 5
(2,514 Views)

Hey James,


As part of that I want to use AVX instructions which are more efficient if you can get data aligned on 16 byte boundaries however LabVIEW is aligned on 8 byte boundaries in 64 bit (based on clusters in http://zone.ni.com/reference/en-XX/help/371361P-01/lvconcepts/how_labview_stores_data_in_memory/. It says arrays are as well but doesn't say to what boundary).


Regarding arrays: I understand from the array section of the page you linked that the array itself (=first dimension integer) and the array content's first element are both aligned to the underlying operating system's boundaries. The OS's boundaries are described e.g. on the same page, a bit further down:

For the platforms on which LabVIEW runs, the alignment constraints are as follows:

  • (Windows 32-bit) Data is aligned only to 1-byte boundaries.
  • (OS X and Linux) Data is aligned naturally up to 4-byte boundaries.
  • (Phar Lap ETS, VxWorks, Windows 64-bit) Data is aligned naturally up to 8-byte boundaries.

Therefore, on e.g. Windows 64 you will get some 8-byte alignment by default, but no 16-byte alignment.

 

Taking all into account, full 16-byte alignment (array itself plus each element) of an 1D-array needs three things:

  • Alignment of the first dimension integer. This is hard to achieve.
  • Alignment of the first element: Make sure the dimension integer / number is 128 bits wide. I am not aware of a way to do so, e.g. using a 2D array instead, having two 64-bit integers, at the sake of extra memory consumption.
  • Alignment of all consecutive elements: This needs the elements to be 128 bits wide. LabVIEW only has EXT, CDB (complex DBL), and "128-bit time stamp" available in 128 bit.

However, this leads to other workaround, where a C-solution seems easier to me.


Ingo – LabVIEW 2013, 2014, 2015, 2016, 2017, 2018, NXG 2.0, 2.1, 3.0
CLADMSD
Message 3 of 5
(2,481 Views)

@ikaiser wrote:

Hey James,

  • Alignment of all consecutive elements: This needs the elements to be 128 bits wide. LabVIEW only has EXT, CDB (complex DBL), and "128-bit time stamp" available in 128 bit.

All of these won't work since on C level these are not 16 byte entities.

- Timestamp is a struct with an int64 for the seconds and an uInt64 for the fractional part.

- CDB is a struct with a double for the real part and a double for the imaginary part

- EXT is an 80 bit entity on Windows 32-bit, and most likely a double on Windows 64 bit. Visual C itself, which is used to compile LabVIEW for Windows, does not support the extended format at all. The LabVIEW developers did create their own assembly code library to support it but maintenance of such a beast is terrible and porting to 64 bit is almost impossible since Intel more or less disabled that format on x64 CPUs especially if you want to make use of MMX or higher instructions.

 

Since the underlaying actual datatype in C is  not 16-bytes (but a combination of 2 8-byte values in a struct, there is no way the C compiler would align the struct itself to 16 bytes.

 

Never mind that the flattened format for an EXT is always extended to 16-bytes, but there is currently no LabVIEW platform which uses all these bytes when the value is in memory. LabVIEW for Sun Sparc and HP-Unix used to support this format but it was implemented in a software library (which was part of the OS, rather than directly on a hardware floating point engine, so was relatively slow compared to standard floating point operations.

 

And unlike my previous answer to this same question where I posed the option to create an array of uInt32 in LabVIEW and account for a possible alignment by either using an offset of 1 or 3 into that array, I have to say that this will not work after more pondering. A LabVIEW array can get copied by the compiler and each copy operation can change that alignment of the actual start of the array in respect to a 16 byte boundary so the original carefully maintained offset when the array was created would be potentially wrong after every copy operation.

 

The only feasable option is to completely manage those arrays in C and treat them in LabVIEW as a pointer only.

 

UPtr ptr = _aligned_malloc(size, 16);

This is a Visual C ism, so other compilers will use other functions.

Rolf Kalbermatter
My Blog
Message 4 of 5
(2,458 Views)

Thanks for all the responses - it sounds like if I want it aligned it will just have to be C pointers passed around my code.

 

The good news is with some further research, many people say the performance penalty in AVX for unaligned data is quite small, so perhaps I can simply ignore this requirement. I shall do some benchmarking in either case and see how it looks.

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
Message 5 of 5
(2,443 Views)