В Matlab я пытаюсь векторизовать свой код, чтобы сократить время моделирования. Однако в результате я получил снижение общей эффективности.
Чтобы понять это явление, я создал 3 разные функции, которые делают то же самое, но с другим подходом:
Основной файл:
clc,
clear,
n = 10000;
Value = cumsum(ones(1,n));
NbLoop = 10000;
time01 = zeros(1,NbLoop);
time02 = zeros(1,NbLoop);
time03 = zeros(1,NbLoop);
for test = 1 : NbLoop
tic
vector1 = function01(n,Value);
time01(test) = toc ;
tic
vector2 = function02(n,Value);
time02(test) = toc ;
tic
vector3 = function03(n,Value);
time03(test) = toc ;
end
figure(1)
hold on
plot( time01, 'b')
plot( time02, 'g')
plot( time03, 'r')
Функция 01:
function vector = function01(n,Value)
vector = zeros( 2*n,1);
for k = 1:n
vector(2*k -1) = Value(k);
vector(2*k) = Value(k);
end
end
Функция 02:
function vector = function02(n,Value)
vector = zeros( 2*n,1);
vector(1:2:2*n) = Value;
vector(2:2:2*n) = Value;
end
Функция 03:
function vector = function03(n,Value)
MatrixTmp = transpose([Value(:), Value(:)]);
vector = MatrixTmp (:);
end
Синий график соответствует циклу for.
n = 100:
n = 10000:
Когда я запускаю код с n = 100
, более эффективным решением является первая функция с циклом for. Когда n = 10000
Первая функция становится менее эффективной.
- У вас есть способ узнать, как и когда правильно заменить цикл for векторизованным аналогом?
- Какое влияние оказывает поиск по индексу с массивом огромных размеров?
- Вычисляет ли Matlab по-другому массив размерности 3 или выше, чем массив размерности 1 или 2?
- Есть ли умный способ заменить цикл while, который использует результат итерации для следующей итерации?
timeit
вместо _2 _ / _ 3_. Поскольку вы написали свои тесты как функции, переключиться на использованиеtimeit
должно быть легко. Также будет полезно, если вы отредактируете свой вопрос, включив в него графики, чтобы нам не пришлось запускать ваш код. чтобы увидеть результаты. - person Wolfie   schedule 30.08.2019timeit
, и _2 _ / _ 3_ имеют ограниченную точность. Помимо повторения вашей процедуры несколько тысяч раз и измерения совокупных показателей, используйте сторонние таймеры, такие как этот, если вам нужно больше точности. Кроме того, ни одна из ваших функций не кажется мне векторизацией, которая более или менее связана с использованием собственных функций Matlab для задач, охватывающих весь массив - итератор не включен, аfunction03
не использует свой первый ввод. - person Argyll   schedule 01.09.2019logical
? - person Chewbaka   schedule 02.09.2019timeit
имеет очень высокую точность. Он вычисляет, сколько раз запускать ваш код для получения значимых значений, он предварительно нагревает среду и выясняет, какие накладные расходы связаны с циклом, чтобы удалить это из времени. Предложенная вами альтернатива ничего из этого не делает. Не думаю, что это хорошо. - person Cris Luengo   schedule 02.09.2019timeit
достигает точности вывода, которая часто равна E-11 в секундах. Я не знаю, является ли такая точность просто тем, чтоtic/toc
обычно делят на количество повторений или выполняется надлежащий статистический анализ. Ты? В любом случае, пакет Houtzager выводит пикосекунды. Принимая во внимание чистую монету, его пакет, кажется, может получить максимально возможную точность от времени часов процессора, в то время какtimeit
не может. - person Argyll   schedule 02.09.2019timeit
на самом деле не применимы. - person Argyll   schedule 02.09.2019timeit
измеряет количество повторений кода, достаточное для того, чтобы разница во времени была значимой, затем повторяет измерение, чтобы избежать ошибок из-за других фоновых заданий. - person Cris Luengo   schedule 02.09.2019timeit
, вы можете увидеть Запись Стива или простоedit timeit
. - person Cris Luengo   schedule 02.09.2019