LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Speed up CIN/DLL

Hi

I have included some C-Code which handels two dimensional arrays of integers
(e.g. 500x500 integers) with a CIN in LabView 5.1. This CIN is called
repeatedly with different arrays.
Can I expect any computing time improvement if I use a DLL instead?

Thanks in advance
Gerd
0 Kudos
Message 1 of 13
(4,183 Views)
Gerd,

You should see no difference in the execution speed between a similiarly written CIN and DLL. Since you have the CIN working I wouldn't bother with the DLL unless you need other advantages that a DLL provides such as portability and maintainability.

Marc M.
0 Kudos
Message 2 of 13
(4,180 Views)
Hi everybody,

even if this thread is rather old I hope somebody still has a look on it. I am facing the following problem:

I need to transfer a 2-dimesional array from a CIN into LabVIEW. It is working alright and the code more or less only involves a call to

NumericArrayResize and afterwards a memcpy

However the memcpy is extremly slow within the CIN. I did some measurement and if I compile the same code as native C code the memcpy gets executed about 10 times faster. Can anybody tell me why? At current state LabVIEW can't be used because the whole stuff is just too slow...

Thanks,

Stefan
0 Kudos
Message 3 of 13
(4,056 Views)
Could you post a code snippet or a simple example that demonstrates the behavior you describe?
 
Kind Regards,
E. Sulzer
Applications Engineer
National Instruments
0 Kudos
Message 4 of 13
(4,046 Views)
Thank you very much for replying.

This is more or less the CIN code I am using:

#include <windows.h>
#include "extcode.h"
#include "hosttype.h"
#include <image.h>

#ifdef __cplusplus
  extern "C" {
#endif

typedef struct
{
    int32 dimSizes[2];
    uInt8 arg1[1];
} TD1;
typedef TD1 **TD1Hdl;


CIN MgErr CINRun(TD1Hdl ImageIn, uInt32 *WidthIn, uInt32 *HeightIn, uInt32 *Ptr_to_image_data_IN, LVBoolean *Success_)
{
    *Success_ = LVFALSE;

    if(*Ptr_to_image_data_IN)
    {
        LPIMAGE image = (LPIMAGE)(*Ptr_to_image_data_IN);
        if(image)
        {
            NumericArrayResize(uB, 2L, (UHandle*)&ImageIn, image->lHeight * image->lWidth);
            (*ImageIn)->dimSizes[0] = image->lWidth;
            (*ImageIn)->dimSizes[1] = image->lHeight;
            // meassuring time before and after this line was done to get the result
            memcpy((*ImageIn)->arg1, image->pData, image->lWidth*image->lHeight);
            *Success_ = LVTRUE;
        }
    }
    return noErr;
}

#ifdef __cplusplus
  }
#endif

This then get compiled using Visual Studio 6 or 2005 into a DLL and afterwards I call

lvsbutil -c $(TargetName) -d GetImageData

Execution speed on a AMD Athlon XP 2200+ for the memcpy line under LabView (even when compiled into an executable) is something around 15-20 ms for a image size of about 400K pixels, while if I copy the very same image using the very same memcpy line in a console application build with the same compiler gets executed in about 2 ms…

Very strange in my opinion, but maybe I made a mistake?

Any help or suggestion is appreciated! I am kind of desperate already 😉

Regards,

Stefan

0 Kudos
Message 5 of 13
(4,034 Views)
Hi,

I did some more tests and maybe the poor performance is not actually based on the memcpy but on some forced thread/task switch, because I noticed that if the code is rearraged like that(this might variy on the used compiler):

... same as the old post
memcpy( (*ImageIn)->arg1, image->pData, image->lPitch*image->lHeight );
memcpy( (*ImageIn)->arg1, image->pData, image->lPitch*image->lHeight );
...

or even

memcpy( (*ImageIn)->arg1, image->pData, image->lPitch*image->lHeight );
memcpy( (*ImageIn)->arg1, image->pData, 1 );

now the 2nd call to the memcpy costs me around 15ms while the first one is fast (I added timestamped OutputDebugString calls between the lines). This is even true for the 2nd version where the 2nd call to memcpy just moves 1 byte?! Very, very strange. Could this be an issue related to the way LabVIEW executes CIN Code? I thought, that during a call to a CIN LabVIEW doesn't execute any other code so therefore I see no reason for a task switch or whatever is happening here?

Regards,

Stefan
0 Kudos
Message 6 of 13
(4,027 Views)


@anotherStefan wrote:
Hi,

memcpy( (*ImageIn)->arg1, image->pData, image->lPitch*image->lHeight );
memcpy( (*ImageIn)->arg1, image->pData, 1 );

now the 2nd call to the memcpy costs me around 15ms while the first one is fast (I added timestamped OutputDebugString calls between the lines). This is even true for the 2nd version where the 2nd call to memcpy just moves 1 byte?! Very, very strange. Could this be an issue related to the way LabVIEW executes CIN Code? I thought, that during a call to a CIN LabVIEW doesn't execute any other code so therefore I see no reason for a task switch or whatever is happening here?

Regards,

Stefan


Since you are already using a LabVIEW manager function (NumericArrayResize) why not use another one too namely MoveBlock(). Maybe that this function is working different.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 7 of 13
(4,018 Views)
Hi Rolf,

well in fact I tried the MoveBlock function as well but with the same result. In the end I couldn't think of a faster way to move a block of memory then the way provided by memcpy if we stick to C. I suspect MoveBlock will call memcpy internally as well. There must be something I am missing. Regarding my assumption of the time loss as result of task switch: Please ignore that one as when copying larger blocks there is a linear increase in time. For a 4MB block of data the time needed on and average system (P4 2.6GHz) is around 200-250 ms! Hasn't anybody else encountered this problem before? I tried LV 5, 7 and 8 by now and always the performance was extremly poor...

Regards,

Stefan
0 Kudos
Message 8 of 13
(4,009 Views)
Hi,
why don't you initialize an array with the coresponding dimensions and use something like this:

void

 imagecopy(unsigned char * ImageIn, unsigned long *WidthIn,unsigned long *HeightIn,unsigned char *Ptr_to_image_data_IN, LVBoolean *Boolean)

{

MoveBlock(Ptr_to_image_data_IN,ImageIn,(*WidthIn)*(*HeightIn));

}

with a 1600x1200 jpeg image I get maximum 5ms execution time on a 1.7 Gz pentium processor

0 Kudos
Message 9 of 13
(4,000 Views)

Dear Cosmin,

thanks for that suggestion. Even if the 'real' source of the problem seems to be located somewhere else today I made some progress. First of all I replaced the calls to memcpy by MoveBlock, which didn't seem to change anything as I expected. Then I modified the code, in a way that 'NumericArrayResize' is only called when the array passed to the CIN differs in size from the buffer I need to copy. Again no change in performance. Then I went back into LabVIEW and called the VI containing the CIN directly. I didn't mention that before because I couldn't imagine that this has impact on the whole issue and I still don't really understand it.

My old version under LabVIEW looked like this:

One top level VI which in a case struct depending on the type of data included a call to 3 sub-VIs. One for 8, one for 16 and one for 32-bit data. Each calls into a CIN with the copy code for the correct data type, which might be very silly but that day I couldn't think of any other solution. The top level VI however returns a 32bit array always, while the low level VIs either return an 8, 16 or 32 bit array. I now suspect, that this 8 bit array returned by the CIN get silently converted into a 32 bit array and this is the real bottleneck. However if I call the 8 bit version directly the performance looks much better. The points I don't understand are:

- Is this conversion from an 8 to a 32 bit array actually done?
- why measuring time inside the CIN produced the results I wrote about earlier while I thought that a CIN is never interrupted?
- have I earned the jerk of the week award for what I did? 😉

Anyway: I would like to thank anybody who answered my pleads! Thanks a lot!!!

Stefan

0 Kudos
Message 10 of 13
(3,990 Views)