필터 지우기
필터 지우기

Improving speed in while loop

조회 수: 9 (최근 30일)
SvB
SvB 2018년 1월 23일
편집: SvB 2018년 2월 1일
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
Adam
Adam 2018년 1월 24일
"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.

댓글을 달려면 로그인하십시오.

채택된 답변

Jan
Jan 2018년 1월 23일
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
SvB
SvB 2018년 1월 24일
편집: SvB 2018년 2월 1일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by