MATLAB Magical Mystery хронометраж - PullRequest
3 голосов
/ 21 августа 2009

Я испытываю очень странное временное поведение в написанной мной функции. Если я оберну свою функцию в другую пустую контейнерную функцию, она получит ускорение в 3 раза.

>> тик; Foo (арг); TOC

прошедшее время: ~ 140 секунд

>> крестики; бар (арг); TOC

прошедшее время: ~ 35 секунд

Вот кикер - определение бара ():

определить бар (аргументы)

Foo (арг)

конец

Существует ли какая-то оптимизация, которая запускается в MATLAB для вызовов вложенных функций? Должен ли я добавлять фиктивную функцию к каждой функции, которую я пишу?

Ответы [ 4 ]

3 голосов
/ 18 марта 2010

Насколько мне известно, ускоритель JIT не работает с выражениями командной строки. Таким образом, когда вы запускаете "tic; foo (args); toc", код foo полностью выполняется в интерпретаторе MATLAB. Однако, когда вы запускаете "tic; bar (args); toc", bar интерпретируется в интерпретаторе, и JIT-акселератор делает попытку компилировать вызов foo () для собственного кода.

Я действительно машу руками над деталями, но в этом суть. Трудно найти подробности о возможностях JIT в MATLAB; большая часть того, что я нашел, находится в блоге Лорен на The MathWorks. Ближайшее авторитетное утверждение, которое я могу найти о командной строке только для интерпретатора, находится здесь: http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/#comment-207

1 голос
/ 21 августа 2009

Я не знаю, пытались ли вы запустить свой код несколько раз, но я заметил одно потенциальное объяснение, что самый первый запуск обновленного файла обычно медленнее, чем последующие (я полагаю, из-за компиляции) , Я предполагаю, что вы можете увидеть различное время для третьей строки следующего (вызываемого после изменения foo):

tic; foo(args); toc;  % First call of foo
tic; bar(args); toc;  % Second call of foo inside bar
tic; foo(args); toc;  % Third call of foo
1 голос
/ 23 августа 2009

Это удивительное поведение. Промежуточный вызов функции не должен так ускоряться.

Попробуйте его профилировать и посмотрите, где он проводит свое время. Это лучший первый вариант почти для любого "Почему мой код Matlab медленный?" вопрос.

clear all
profile on -timer real
foo(args);
profile report
%read the report and save a screencap
clear all
profile clear
bar(args);
profile report

Там заканчивается совет. Здесь начинается предположение.

Есть две вещи, которые отличаются в двух вызовах. Существует взаимодействие рабочего пространства. Вызов foo () из командной строки может оставить переменную ans в вашем рабочем пространстве. Когда вызывается из bar (), ANS будет установлен, но затем сразу очищается, когда bar () возвращается. Кроме того, foo () может использовать evalin () / assignin () для просмотра рабочих пространств вверх по стеку вызовов и может взаимодействовать с переменными, назначенными в вашей базовой рабочей области. Функция bar () имеет чистое рабочее пространство.

В зависимости от того, где находится bar.m, он может фактически вызывать другой foo (), или, возможно, разрешать его немного по-другому. Проверьте разрешение пути с помощью «which foo» в обоих контекстах.

В зависимости от того, как определено «args», для foo могут быть видны различные входные имена ().

Кроме того, foo () может содержать патологический код, который проверяет, вызывается ли он из базовой рабочей области или даже вызывается ли функцией из определенного имени, и ведет себя по-разному в зависимости от этого.

Тем не менее, это в основном должны быть незначительные взаимодействия и не должны вызывать замедление этого порядка. Я подозреваю, что происходит что-то еще, может быть, просто под воздействием немного разных контекстов вызова. Добавление уровня косвенности с помощью bar () не должно быть ответом. Посмотрите, что должен сказать профилировщик и оттуда. Точный код для воспроизведения очень поможет в получении помощи от сообщества.

1 голос
/ 21 августа 2009

Вы пробовали foo второй раз без очистки переменных? Я не могу воспроизвести это увеличение производительности , если я запускаю его несколько раз. Иначе, это кажется быстрее, но это только потому, что MATLAB прекомпилирует эти функции, если вы запустите их один раз.

function barfoo    

    for i = 1:Inf
    end    

end

А,

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