Matlab DLL call time


#1

Hello,

I’m using the Opal Kelly XEM6010 to send commands to/from some custom hardware that my team works with. I wrote the code to interface with the Opal Kelly in Matlab, using their calllib function to run Opal Kelly API functions. It works well enough but I’ve noticed that the throughput is extremely low. When I did a code analysis in Matlab I found that 99.9% of the execution time is tied up in the Opal Kelly API call, even though the amount of data that I’m sending in each call is pretty low - about 9 16-bit words. I find that each time I run calllib to send a new chunk of data, it takes about 3ms to complete the API call.

Anyway, has anyone else observed this problem, and if so what was the solution? Here’s some ideas I’ve been kicking around but I can’t figure out how to confirm/fix the issue. Any help whatsoever would be appreciated.

  1. Maybe the Opal Kelly API is waiting to send the data (and the API call is not returning) until the USB2 frame is complete. As I understand it, USB2 frames have a frequency on the order of 1kHz, so this would explain a good deal of the delay.
  2. Matlab’s calllib is just really inefficient and introduces ~3ms overhead even once the library is loaded?

#2

@joevonpelt

USB 2.0 is not very efficient for small transfers. You’ll notice a fair bit of overhead involved, both in the implementation of FrontPanel and simply USB 2.0 limitations itself.


#3

@joevonpelt

— Begin quote from ____

I’m using the Opal Kelly XEM6010 to send commands to/from some custom hardware that my team works with. I wrote the code to interface with the Opal Kelly in Matlab, using their calllib function to run Opal Kelly API functions. It works well enough

— End quote

I’m trying the same thing at the moment, but cannot seem to get it to work. Is there an updated library for matlab somewhere? I’m using 64-bit matlab, and the 64-bit version of frontpanel (at least presumably since I see both 32 and 64 bit apis in the directories). I can’t seem to get it to work. Matlab keeps choking on trying to get the serial port, the function returns a pointer when it should return a string. Anyone have any thoughts that might help?


#4

I’ve had some problems using loadlibrary() with the newest version of FrontPanel. It seems that they’ve included some C constructs (unions) that the matlab library complier/parser doesn’t like. I’ve gone back to v. 3.1.6. Someday I’ll try to close the loop with Opal Kelly to see if I can get the new front panel drivers working.

Also, there seems to be some odd inconsistencies with whether or not Matlab adds voidPtr to some of the function returns between matlab versions, and whether it requires a buffer length argument. I haven’t tracked down whether or not this is Matlab’s issue or the Opal Kelly library version issue, or even a MSVC version issue. I added some code to parse the call signature and call the available version. It’s kludgy, but it works with the wide combinations of boards, driver versions, and Matlab versions I have hanging around here. Here’s some sample Matlab code:

m = libfunctions(‘okFrontPanel’);
if any(strcmp(m, ‘okUsbFrontPanel_Construct’))
lib_fcn_str = ‘okUsbFrontPanel’;
elseif any(strcmp(m, ‘okFrontPanel_Construct’))
lib_fcn_str = ‘okFrontPanel’;
else
error(‘Prefix of okFrontPanel library not found’)
end

% [cutting construct call, and some other stuff]

% Get the string that Matlab things the call consists of
OKfunctions = libfunctions(‘okFrontPanel’, ‘-full’);

fcn_signature = [obj.lib_fcn_str ‘_GetDeviceListSerial’]; %sample function signature

lib_fcn_signature = OKfunctions{~cellfun(@isempty, strfind(OKfunctions, fcn_signature ))};

% Split apart this function declaration, e.g. ‘cstring okFrontPanel_GetDeviceListSerial(uint64, int32, cstring)’
fcnparts = strsplit(lib_fcn_signature, {’ ‘,’(’,’)’}, ‘CollapseDelimiters’, true);

if length(fcnparts) > 6
[sn] = calllib(‘okFrontPanel’, [lib_fcn_str ‘_GetDeviceListSerial’], obj.xptr, 0, ’ ', 10);
else
[sn] = calllib(‘okFrontPanel’, [lib_fcn_str ‘_GetDeviceListSerial’], obj.xptr, 0, ’ ');
end

(I lifted these snippets from my own code - I might have omitted something, but looking through it should get you started)

Best,
Rich