使用Matlab parfeval的性能损失?

时间:2017-06-20 16:47:52

标签: matlab parallel-processing

我有一个相对较大的文件,我想使用GUIDE绘制一个交互式绘图,绘制文件的一部分,并在scrollEvent上更新窗口。 (数据适当重新绘制)。

为此,获取大小为窗口大小4倍的缓冲区,当窗口的中心达到缓冲区的75%时,将重新获取缓冲区,以便窗口位于新缓冲区的中心。

问题在于,当使用fread时,它当然会阻塞直到完成。(这在视觉上令人不安)

我尝试创建一个单独的readData函数,该函数使用f = parfeval(gcp(),@readData,1,datafile)进行调用,而[~,buffer]=fetchNext(f) buffer将保留handles.datafile

问题:即使在我的示例中(见下文)readData只调用一次,但每次后续绘图都非常慢(不使用parfeval时的运行时间的10倍)。

示例:

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

生成

**这是获取异步代码的同步代码,注释掉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

1 个答案:

答案 0 :(得分:1)

这确实非常神秘。问题似乎是guidataparallel.FevalFuture返回的parfeval之间的某种互动。作为一种解决方法,您可以简单地避免覆盖结构的该元素。换句话说,删除行

handles.data.fileReader = -1;

您还需要检查handles.data.fileReader.Read,确保在已完成的未来再次尝试再次致电fetchNext