Векторизованный подход
Вы можете выполнить матричное умножение между A и транспонировать B, затем суммировать по dim-2 и, наконец, выполнить поэлементное деление с L -
result = sum(A.*B.',2)./L
Бенчмаркинг
В этом разделе рассматриваются тесты времени выполнения и ускорения для proposed approach по сравнению с loop-based approach, как указано в начале вопроса. Обратите внимание, что другой подход на основе diag, предложенный во второй части вопроса, не был охвачен в этих тестах, поскольку время выполнения с ним было сравнительно очень большим.
Код сравнительного анализа
N_arr = 4000:4000:100000; %// Datasizes
timeall = zeros(2,numel(N_arr)); %// Array to store runtimes
for iter = 1:numel(N_arr)
%// Create random inputs
N = N_arr(iter);
A=rand(N,4); B=rand(4,N); L=rand(N,1);
%// Time the approaches
f = @() mult_twomat_loopy(A,B,L);
timeall(1,iter) = timeit(f); clear f
f = @() mult_twomat_vect(A,B,L);
timeall(2,iter) = timeit(f); clear f
end
%// Plot speedups
figure,hold on,grid on
plot(N_arr,timeall(1,:)./timeall(2,:),'-bo')
xlabel('Datasize, N(Rows in A)'),ylabel('Speedup Factor (x)')
title('Speedup Plot')
Связанные функциональные коды
mult_twomat_loopy.m:
function result = mult_twomat_loopy(A,B,L)
N = size(A,1);
result = zeros(N,1);
for i=1:N
result(i)=A(i,:)*B(:,i)/L(i);
end
mult_twomat_vect.m:
function result = mult_twomat_vect(A,B,L)
result = sum(A.*B.',2)./L;
Ускорение предлагаемого подхода по сравнению с зацикленным

Выводы
Как видно из графика ускорения, предложенный подход кажется очень хорошим вариантом для решения проблемы. Интересным наблюдением из графика снова является внезапное падение производительности для предлагаемого подхода по сравнению с зацикленным подходом для 32K+ datasizes. Причиной этого провала, скорее всего, является пропускная способность системной памяти, ограничивающая производительность при таких больших размерах данных, но, к счастью, даже для таких размеров данных ускорение все еще сохраняется на отметке более 20x.
person
Divakar
schedule
02.02.2015