MATLAB Matrix Preallocation медленнее, чем динамическое расширение матрицы - PullRequest
2 голосов
/ 02 марта 2011

В каждой итерации цикла я вычисляю матрицу MATLAB.Все эти матрицы должны быть объединены вместе, чтобы создать одну окончательную матрицу.Я знаю размеры этой окончательной матрицы перед входом в цикл, так что я, хотя предварительное выделение матрицы с использованием функции 'нулей', будет быстрее, чем инициализация пустого массива, а затем просто добавление подмассивов в каждой итерации моего цикла.Как ни странно, моя программа работает НАМНОГО медленнее, когда я предварительно выделяю.Вот код (отличаются только первая и последняя строки):

Это медленно:

w_cuda = zeros(w_rows, w_cols, f_cols);

for j=0:num_groups-1

    % gets # of rows & cols in W. The last group is a special
    % case because it may have fewer than max_row_size rows
    if (j == num_groups-1 && mod(w_rows, max_row_size) ~= 0)
        num_rows_sub = w_rows - (max_row_size * j);    
    else
        num_rows_sub = max_row_size;
    end;

    % calculate correct W and f matrices
    start_index = (max_row_size * j) + 1;
    end_index = start_index + num_rows_sub - 1;

    w_sub = W(start_index:end_index,:);
    f_sub = filterBank(start_index:end_index,:);

    % Obtain sub-matrix
    w_cuda_sub = nopack_cu(w_sub,f_sub);

    % Incorporate sub-matrix into final matrix
    w_cuda(start_index:end_index,:,:) = w_cuda_sub;

end

Это быстро:

w_cuda = [];

for j=0:num_groups-1

    % gets # of rows & cols in W. The last group is a special
    % case because it may have fewer than max_row_size rows
    if (j == num_groups-1 && mod(w_rows, max_row_size) ~= 0)
        num_rows_sub = w_rows - (max_row_size * j);    
    else
        num_rows_sub = max_row_size;
    end;

    % calculate correct W and f matrices
    start_index = (max_row_size * j) + 1;
    end_index = start_index + num_rows_sub - 1;

    w_sub = W(start_index:end_index,:);
    f_sub = filterBank(start_index:end_index,:);

    % Obtain sub-matrix
    w_cuda_sub = nopack_cu(w_sub,f_sub);

    % Incorporate sub-matrix into final matrix
    w_cuda = [w_cuda; w_cuda_sub];

end

Что касается другихпотенциально полезная информация - моя матрица трехмерна, а числа внутри нее сложны.Как всегда, любые знания приветствуются.

1 Ответ

7 голосов
/ 02 марта 2011

Я всегда предполагал, что предварительное распределение быстрее для любого размера массива, и никогда не проверял его.Итак, я выполнил простой тест, рассчитывающий время для заполнения массивов разных размеров от 1x1x3 до 20x20x3, используя 1000 итераций с помощью методов добавления и предварительного выделения.Вот код:

arraySize = 1:20;
numIteration = 1000;

timeAppend = zeros(length(arraySize), 1);
timePreAllocate = zeros(length(arraySize), 1);

for ii = 1:length(arraySize); 
    w = [];
    tic;
    for jj = 1:numIteration
        w = [w; rand(arraySize(ii), arraySize(ii), 3)];
    end
    timeAppend(ii) = toc;
end; 

for ii = 1:length(arraySize); 
    w = zeros(arraySize(ii) * numIteration, arraySize(ii), 3);
    tic;
    for jj = 1:numIteration
        indexStart = (jj - 1) * arraySize(ii) + 1;
        indexStop = indexStart + arraySize(ii) - 1;
        w(indexStart:indexStop,:,:) = rand(arraySize(ii), arraySize(ii), 3);
    end
    timePreAllocate(ii) = toc;
end; 

figure;
axes;
plot(timeAppend);
hold on;
plot(timePreAllocate, 'r');
legend('Append', 'Preallocate');

А вот (как и ожидалось) результаты: Comparison of array appending vs. preallocation

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...