Borrar filtros
Borrar filtros

Improving speed in while loop

9 visualizaciones (últimos 30 días)
SvB
SvB el 23 de En. de 2018
Editada: SvB el 1 de Feb. de 2018
This is a quite specific example, but any help is welcome.
I have a motorized pan-tilt system with the corresponding Matlab functions to make it move to a set position and read out the Azimuth & Elevation at any time. I'm having the system swivel from left to right and back and forth for 2 minutes, and need to register its rotation as often as possible. Currently, it manages ~17 positions per second, but I'm hoping to reach 50 (~20ms/loop).
Below you can find the code, but the general setup within the while loop is as follows:
  • Check current time
  • Get current position
  • Write time & position to new line in an open file.
  • Check whether current position is at earlier defined limit, if yes, start moving in the opposite direction.
  • Repeat.
Note that ultimately I want to do runs of up to 2 hours, and to prevent data loss in case of an error I start a new "position log file" every minute. The target computer doesn't have matlab, but runs a compiled version of this code with the required runtime.
Can this code be made any faster, assuming the Pan-Tilt functions have been optimized? I think the slowest part is in the fprintf, but I'm not sure how to reduce the load here.
Any help is welcome, thanks!
% Move back and forth between two limit positions.
TS(1,:) = clock; %TS = TimeStamp
tic
timelimit = toc;
while timelimit<125 % Run for slightly over 2 minutes
timelimit = toc;
% Get position
[pan,tilt]=GetPos(SSS,obj1);
% Save position in Log File
% Prepare data for input
TS(2,:) = clock; %TimeStamp
data = [TS(2,:) pan tilt PanSpeed TiltSpeed]; %Time, panposition, tiltposition, panspeed, tiltspeed
% Check: Has a minute passed? If no, just write data. If yes, close file and start new one.
if TS(2,5) == TS(1,5) % Check if still same minute
% Add line with filename & data
fprintf(fileID,FormatSpec,data);
else
fclose(fileID);
filename = sprintf('%02d_%02d',TS(2,4),TS(2,5)); % Filename has hours and minutes, with leading 0 if necessary.
fileID = fopen(fullfile(LogPath,strcat(filename,'.txt')),'wt');
fprintf(fileID,FormatSpec,data);
end
TS(1,:) = TS(2,:);
% Check whether left or right limit has been reached.
if abs(pan-PanLimRight) < 500 && GoRight == 1
IsRight = 1;
elseif abs(pan-PanLimLeft) < 500 && GoLeft == 1
IsLeft = 1;
end
if IsLeft == 1 && GoLeft == 1 % If left limit has been reached (while moving left)
%Move right
StopMotion(SSS,obj1);
GoToPosRate_NW(SSS,PanSpeed,PanLimRight,TiltSpeed,TiltLimRight,MMM,obj1);
GoLeft = 0;
GoRight = 1;
IsLeft = 0;
end
if IsRight == 1 && GoRight == 1 %If right limit has been reached (while moving right)
% Move left
StopMotion(SSS,obj1);
GoToPosRate_NW(SSS,PanSpeed,PanLimLeft,TiltSpeed,TiltLimLeft,MMM,obj1);
GoLeft = 1;
GoRight = 0;
IsRight = 0;
end
end
  1 comentario
Adam
Adam el 24 de En. de 2018
"I think the slowest part is in the fprintf"
Never do optimisation work based on 'I think'. The Matlab profiler is excellent and trivially simple to use compared to profilers for languages like C++ (at least last time I used a C++ profiler).
doc profile
will give you details and you can be finding all the information you need about which parts are slow in no time at all. It won't tell you how to speed them up of course, but there's nothing worse when optimising code than just making assumptions and putting a lot of effort into speeding up something that actually only takes 2% of the total time anyway so that even an amazing speedup in that component will only ever make your code < 2% faster.

Iniciar sesión para comentar.

Respuesta aceptada

Jan
Jan el 23 de En. de 2018
I'd change the fopen('wt') to fopen('W') (upper-case W for buffering), but I do not assume that this changes the runtime remarkably.
if IsLeft && GoLeft might be slightly faster, but again, that change is minimal.
The posted code does not contain obvious slow commands. Maybe collecting the data in the RAM is faster than writing to the disk. Especially if this is a real-time approach, an automatic start of the disk fragmentation would let the system fail.
But the actual time consuming parts would be revealed by the profiler: Run it and check, where the most time is used. I guess, that it is GetPos(), StopMotion() and GoToPosRate_NW(). Then the shown code cannot influence the total run time substantially. Remember that accelerating a piece of code by (impossible) 100% will accelerate the total code by 1% only, , if it uses 1% of the total time only. So focus on the bottlenecks only: Use the profiler to find, where time can be saved at all.
  1 comentario
SvB
SvB el 24 de En. de 2018
Editada: SvB el 1 de Feb. de 2018
Thanks, good to hear there are at least no obvious slowdowns so far. The profiler was new for me. Unfortunately, it doesn't seem to run after compiling to a standalone program, and the actual computer that interfaces with the pan-tilt does not have Matlab. Might have to arrange for that in the end.
I'll also have a look at storing data in the RAM and then writing to HD every 1-2 minutes only. That might cause a hiccup at that point, but hopefully yields batches of 2 minutes of good data. We'll see.
EDIT: Ultimately accepted your answer since it does provide info on how to (slightly) speed up the code - not sure one could do more with the information I provided. I indeed later learned that GetPos() is the slowest part, so the loss of time is in communication with the hardware, not in Matlab itself.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Productos

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by