Ich habe eine relativ große Datei und ich möchte ein interaktives Plot mit GUIDE erstellen, das ein Segment der Datei plottet und bei scrollEvent wird das Fenster aktualisiert. (Die Daten werden entsprechend neu erstellt).Leistungsverlust mit Matlab parfeval?
Zu diesem Zweck wird ein 4-mal größerer Puffer als das Fenster abgerufen, und wenn der Mittelpunkt des Fensters 75% des Puffers erreicht, wird der Puffer erneut abgefragt, so dass sich das Fenster im Mittelpunkt des neuen Puffers befindet.
Das Problem dabei ist, dass, wenn fread
es natürlich Blöcke mit bis getan. (Die optisch störend ist)
Was ich ist versucht, eine separate readData
Funktion zu schaffen, die mit f = parfeval(gcp(),@readData,1,datafile)
und auf [~,buffer]=fetchNext(f)
die buffer
aufgerufen wird wird auf handles.datafile
beibehalten.
Problem: Auch wenn in meinem Beispiel (siehe unten) readData
wird nur einmal aufgerufen, jede nachfolgende Plotten unglaublich langsam ist (10x die Laufzeit, wenn nicht parfeval
verwenden).
Beispiel:
./test.dat
von dd if=/dev/urandom of=test.dat bs=100000 count=1024
generiert wurde ** Dies ist der Synchroncode des asynchronen eins zu bekommen, kommentieren Sie die parfeval
und fetchNext
Funktionsdefinitionen, die parallel diejenigen Shadowing.
function test()
f = figure('Toolbar','none','Menubar','none');
ax = axes(f);
data = struct( 'file','./test.dat',...
'buffer',[],...
'window',[0,100000]);
p = gcp();
data.fileReader = parfeval(p,@readData,1,data);
handles = struct('axes',ax,'figure',f,'data',data);
guidata(f,handles);
set(f,'WindowScrollWheelFcn',@scrollHandler);
end
function f = parfeval(~,fun,~,in1)
f = struct('output',fun(in1));
end
function [id,out] = fetchNext(f,varargin)
id = 1;
out = f.output;
end
function buffer = readData(data)
file = fopen(data.file,'r');
buffer = fread(file,[128,400000],'int16');
fclose(file);
end
function scrollHandler(hObject, eventdata, ~)
handles = guidata(hObject);
ax = handles.axes;
C = get (ax, 'CurrentPoint');
XLim = get(ax, 'XLim');
YLim = get(ax, 'YLim');
if XLim(1)<=C(1,1) && XLim(2)>=C(1,1) && ...
YLim(1)<=C(1,2) && YLim(2)>=C(1,2)
tic;
window = handles.data.window;
if isstruct(handles.data.fileReader) || handles.data.fileReader ~= -1
fprintf('Reading from file\n');
[~,handles.data.buffer] = fetchNext(handles.data.fileReader);
handles.data.fileReader = -1;
end
if eventdata.VerticalScrollCount > 0 && window(2) < 399000
window = window + 1000;
else
if window(1) > 1000
window = window - 1000;
end
end
handles.data.window = window;
guidata(hObject, handles);
plot(ax,handles.data.buffer(65,window(1)+1:window(2)));
toc
end
end
Ich habe versucht, dies mit Ihrem Code zu reproduzieren, aber es war mir nicht klar, wie Sie damit richtig umgehen. Es wäre sehr hilfreich, wenn Sie eine einfachere Standalone-Code-only-Reproduktion erstellen könnten. Es scheint auch so, als ob du irgendwie andeuten würdest, dass ein einziger vorheriger Aufruf von 'parfeval' irgendwie das anschließende Plotten verlangsamt? – Edric
@Edric hat das Beispiel auf einen Nur-Code aktualisiert. – Adam