Почему система должна ждать завершения gpudevice? - PullRequest
0 голосов
/ 26 января 2019

У меня большая проблема с использованием gpu для ускорения скорости NMF от Liu в matlab.Вот часть кода:

XU = X'*U;  % mnk or pk (p<<mn)
UU = U'*U;  % mk^2
VUU = V*UU; % nk^2
V = V.*(XU./max(VUU,1e-10));
XV = X*V;   % mnk or pk (p<<mn)
VV = V'*V;  % nk^2
UVV = U*VV; % mk^2   
U = U.*(XV./max(UVV,1e-10)); % 3mk
......
newobj = CalculateObj(X, U, V);

Исходные переменные X, U и V являются нормальной матрицей, которая использует CPU для вычисления.И я преобразовываю X в gpuArray с помощью gpuArray, что приводит ко всем вычислениям, использующим gpu.Все идет хорошо до последней строки, в которой рассчитывается функция объекта NMF.Код CalculateObj:

function [obj, dV] = CalculateObj(X, U, V, deltaVU, dVordU)
    if ~exist('deltaVU','var')
        deltaVU = 0;
    end
    if ~exist('dVordU','var')
        dVordU = 1;
    end
    dV = [];
    maxM = 62500000;
    [mFea, nSmp] = size(X);
    mn = numel(X);
    nBlock = floor(mn*3/maxM);
    if mn < maxM
        dX = U*V'-X;
        obj_NMF = sum(sum(dX.^2));
        if deltaVU
            if dVordU
                dV = dX'*U;
            else
                dV = dX*V;
            end
        end
    else
        obj_NMF = 0;
        if deltaVU
            if dVordU
                dV = zeros(size(V));
            else
                dV = zeros(size(U));
            end
        end
        for i = 1:ceil(nSmp/nBlock)
            if i == ceil(nSmp/nBlock)
                smpIdx = (i-1)*nBlock+1:nSmp;
            else
                smpIdx = (i-1)*nBlock+1:i*nBlock;
            end
            dX = U*V(smpIdx,:)'-X(:,smpIdx);
            obj_NMF = obj_NMF + sum(sum(dX.^2));
            if deltaVU
                if dVordU
                    dV(smpIdx,:) = dX'*U;
                else
                    dV = dU+dX*V(smpIdx,:);
                end
            end
        end
        if deltaVU
            if dVordU
                dV = dV ;
            end
        end
    end
   %obj_Lap = alpha*sum(sum((L*V).*V));

    obj = obj_NMF;

Я считаю, что выполнение строки 40 займет много времени, что составляет obj_NMF = obj_NMF + sum (sum (dX. ^ 2)).Поскольку классом dX является gpuArray, а obj_NMF - обычная переменная, похоже, системе необходимо дождаться завершения выполнения gpu до добавления, что займет много времени.Более того, даже если я установил obj_NMF в качестве объекта gpuArray, ему все равно нужно ждать завершения работы gpu.Я хочу знать:

  1. , почему система должна завершить работу gpu?
  2. почему gpu не завершает работу после выполнения строки?
  3. Есть ли какое-либо решение для ускорения процесса?
...