From: Bob on
I am trying to do some high bandwidth processing in MatLab reading a UDP socket.

As much as I try, I can't read more than ~32KBps using the code below.

Is there something I can do to increase the rate at which I can read the UDP datagrams? Or is this a limitation of the IC toolbox?


Using Java I can read at a higher rate, but still not at the rate I am sending. And it seems compiling the java version of the code with 'mcc' is not an option.

Any ideas?

Note: the gui referenced is simply a stop button. the input datastream is coming across a GbE NIC at over ~100Mbps.
================================================

%% init
clear all;

% start GUI
g = gui;
running = 1;

format long;
tnow = tic;

totalBytes = 0;

if ~exist('u', 'var')
global u;
u = udp ('127.0.0.1', 20480, 'LocalPort', 20480); %#ok<TNMLP>
fopen(u);
u.Timeout = 0;

%udpTargetReport(mod(now,1)*86400.0*1e9, [ 1 2 3 4 5 6 7 8 9 10 11 12 ]);

end

while running
try
% check if data available on the socket
n = u.BytesAvailable;

% get data while there is data to read
while n
% read datagram from socket as uint32
[d, nd] = fread(u, n, 'uint8');

% u8 contains message as array of uint8
% u8 = uint8(d);

n = n - nd;

totalBytes = totalBytes + nd;

end

dt = toc(tnow);
if (dt >= 1)

% call ~1Hz processing here, if needed
% disp(dt);
%
fprintf('Bps = %f\n', totalBytes / dt);
tnow = tic;
totalBytes = 0;

%
% see if user pressed stop button
%
pause(0.000000001);
gd = guidata(g);
running = gd.running;
end

catch exception
if 1 == strcmp('MATLAB:guidata:InvalidInput', exception.identifier)
% user closed dialog without pressing stop button
running = 0;
clear g;
else
% probably an i/o exception, lets see it
disp(exception.message);
end

% we either are closing or there was an exception on the socket
% either way, close the socket
if exist('u', 'var')
fclose(u);
delete(u);
clear u;
exit;
end
end
end

%% cleanup
if exist('g', 'var')
close (g);
clear g;
end

if exist('u', 'var')
fclose(u);
delete(u);
clear u;
end
From: Walter Roberson on
Bob wrote:
> I am trying to do some high bandwidth processing in MatLab reading a UDP
> socket.
>
> As much as I try, I can't read more than ~32KBps using the code below.
>
> Is there something I can do to increase the rate at which I can read the
> UDP datagrams? Or is this a limitation of the IC toolbox?

You might wish to experiment with the tcpudpip File Exchange contribution.


> pause(0.000000001);

You could pause(0) if the point is to allow events to be processed.
From: Bob on
>
> You might wish to experiment with the tcpudpip File Exchange contribution.
>

Thanks for the suggestion. I will try it and see what I get.

> You could pause(0) if the point is to allow events to be processed.

And I understand pause(0) SHOULD allow events to be processed, but in my case it doesn't work; pushing the Stop button in the GUI has no effect with pause(0); it works with pause(0.000000001);
From: Bob on
> >
> > You might wish to experiment with the tcpudpip File Exchange contribution.
> >

Results:

XP Win32 --> XP Win64
~100Mbps UDP stream
1468 byte datagrams
reads only 8Mbps.

XP Win64 --> XP Win32
~100Mbps UDP stream
1468 byte datagrams
reads 72Mbps.

Still significant packet loss; very much so with Rx on Win64.

(For those who might suggest larger datagrams, that's not under my control.)

Here's the code:
============================
%% init
clear all;

% start GUI
g = gui;
running = 1;

format long;
tnow = tic;

totalBytes = 0;

udp = pnet('udpsocket',20480);

while running
try
% if the udp socket doesn't exist, create it
% (might be the first time, or there might have been an i/o exception
% to cause the socket to be closed, either way, create it if it
% doesn't exist)
% check if data available on the socket
n = pnet(udp,'readpacket');

% get data while there is data to read
while n
% read datagram from socket as uint32
nd = 1468;

d = pnet(udp,'read',1468,'uint8');

n = n - nd;

totalBytes = totalBytes + nd;
end

dt = toc(tnow);
if (dt >= 1)

% call ~1Hz processing here, if needed
% disp(dt);
%
fprintf('Mbps = %f\n', 8*totalBytes / (1000000*dt));
tnow = tic;
totalBytes = 0;

pause(0.000000001);
gd = guidata(g);
running = gd.running;
end

% check if user stopped us via GUI
catch exception
if 1 == strcmp('MATLAB:guidata:InvalidInput', exception.identifier)
% user closed dialog without pressing stop button
running = 0;
clear g;
else
% probably an i/o exception, lets see it
disp(exception.message);
end

% we either are closing or there was an exception on the socket
% either way, close the socket
if exist('u', 'var')
fclose(u);
delete(u);
clear u;
exit;
end
end
end
From: Trent Jarvi on

"Bob " <bwhite(a)sensis.com> wrote in message
news:huopna$22e$1(a)fred.mathworks.com...
>I am trying to do some high bandwidth processing in MatLab reading a UDP
>socket.
>
> As much as I try, I can't read more than ~32KBps using the code below.
>
> Is there something I can do to increase the rate at which I can read the
> UDP datagrams? Or is this a limitation of the IC toolbox?
>
>
> Using Java I can read at a higher rate, but still not at the rate I am
> sending. And it seems compiling the java version of the code with 'mcc'
> is not an option.
>
> Any ideas?
>
> Note: the gui referenced is simply a stop button. the input datastream is
> coming across a GbE NIC at over ~100Mbps.
> ================================================
>
> %% init
> clear all;
>
> % start GUI
> g = gui;
> running = 1;
> format long;
> tnow = tic;
>
> totalBytes = 0;
>
> if ~exist('u', 'var')
> global u;
> u = udp ('127.0.0.1', 20480, 'LocalPort', 20480); %#ok<TNMLP>
> fopen(u);
> u.Timeout = 0;
>
> %udpTargetReport(mod(now,1)*86400.0*1e9, [ 1 2 3 4 5 6 7 8 9 10 11 12 ]);
>
> end
>
> while running
> try
> % check if data available on the socket
> n = u.BytesAvailable;
>
> % get data while there is data to read
> while n
> % read datagram from socket as uint32
> [d, nd] = fread(u, n, 'uint8');
>
> % u8 contains message as array of uint8
> % u8 = uint8(d);
> n = n - nd;
> totalBytes = totalBytes + nd;
>
> end
> dt = toc(tnow);
> if (dt >= 1)
> % call ~1Hz processing here, if needed
> % disp(dt);
> %
> fprintf('Bps = %f\n', totalBytes / dt);
> tnow = tic;
> totalBytes = 0;
> %
> % see if user pressed stop button
> %
> pause(0.000000001);
> gd = guidata(g);
> running = gd.running;
> end
> catch exception
> if 1 == strcmp('MATLAB:guidata:InvalidInput', exception.identifier)
> % user closed dialog without pressing stop button
> running = 0;
> clear g;
> else
> % probably an i/o exception, lets see it
> disp(exception.message);
> end
> % we either are closing or there was an exception on the socket
> % either way, close the socket if exist('u', 'var')
> fclose(u);
> delete(u);
> clear u;
> exit;
> end
> end
> end
>
> %% cleanup
> if exist('g', 'var')
> close (g); clear g;
> end
>
> if exist('u', 'var')
> fclose(u);
> delete(u);
> clear u;
> end
>

Hi Bob,

ICT historically deals with instruments that communicate with ASCII strings
of data. There is some overhead associated with parsing the lines of ASCII
communication. Since you are doing binary communication, I recommend you
set the terminator to null to avoid extra string based processing of the
data. The throughput improvements can be significant.

....
u = udp ('127.0.0.1', 20480, 'LocalPort', 20480); %#ok<TNMLP>
u.Terminator=''
fopen(u);
u.Timeout = 0;
....

Throughput should then be optimal when you are reading about 9k of data each
read.