2017-06-20 21 views
0

私は比較的大きなファイルを持っており、ファイルのセグメントをプロットするGUIDEを使ってインタラクティブなプロットを作りたいと思っています。そしてscrollEventにウィンドウが更新されます。 (データは適切に再変換される)。Matlab parfevalを使用するとパフォーマンスが低下しますか?

この目的のために、ウィンドウの4倍のサイズのバッファがフェッチされ、ウィンドウの中心がバッファの75%に達すると、ウィンドウが新しいバッファの中央にくるようにバッファが再フェッチされます。

これで問題が行われるまでのコースブロックのfreadそれを使用した場合ということです。(視覚的に邪魔である)

私が試したことはf = parfeval(gcp(),@readData,1,datafile)で呼び出される別々のreadData関数を作成することであり、[~,buffer]=fetchNext(f)bufferhandles.datafileに保持されます。

問題:私の例ではreadDataは一度だけ呼び出されます(下記参照)にもかかわらず、後続のすべてのプロットは(parfevalを使用しない場合の実行時の10倍)非常に遅いです。

例:

./test.datdd if=/dev/urandom of=test.dat bs=100000 count=1024

によって生成された**これは、非同期1を取得するための同期コードで、パラレルなものをシャドーイングparfevalfetchNext関数定義をコメントアウト。

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 
+0

私はあなたのコードを使ってこれを再現しようとしましたが、それを正しく操作する方法がわかりませんでした。あなたがもっと簡単なスタンドアロンのコードのみの複製を作成できるなら、本当に役に立ちます。また、 'parfeval'への以前の呼び出しが何らかの形で後続のプロットを遅くしていることを何とか示唆しているようです。 – Edric

+0

@Edricはこの例をコードのみのものに更新しました。 – Adam

答えて

1

これは本当に非常に不思議です。この問題は、guidataとのやりとりのように思われ、parallel.FevalFutureparfevalによって返されます。回避策として、構造体のその要素を上書きするのを避けることができます。言い換えれば、行を削除

handles.data.fileReader = -1; 

また必ず既に完了し、将来に再びfetchNextを呼び出そうとしないようにするためにhandles.data.fileReader.Readをチェックする必要があります。

+0

これは本当に動作します、ありがとう – Adam

関連する問題