"GLOBAL может быть очень неэффективным"

Я использую (в Matlab) global оператор внутри команды if, так что я импортирую глобальную переменную в локальное пространство имен, только если она действительно нужна.

Анализатор кода предупреждает меня об этомglobal может быть очень неэффективным, если это не оператор верхнего уровня в своей функции ". Размышляя о возможной внутренней реализации, я нахожу это ограничение очень странным и необычным. Я думаю о двух возможностях:

  1. Что на самом деле означает это предупреждение?global очень неэффективен сам по себе, поэтому не используйте его в цикле ". В частности, использование его внутри if, как я делаю, совершенно безопасно, и предупреждение выдается неправильно (и плохо сформулировано)

  2. Предупреждение верно; Matlab использует какой-то действительно необычный механизм загрузки переменных в фоновом режиме, поэтому он значительно медленнее импортирует глобальные переменные внутри оператора if. В этом случае я хотел бы получить подсказку или указатель на то, как эти вещи действительно работают, потому что мне это интересно, и мне кажется важным, если я хочу написать эффективный код в будущем.

Какое из этих двух объяснений является правильным? (а может и нет?)

Заранее спасибо.

РЕДАКТИРОВАТЬ: чтобы прояснить: я знаю, что global медленный (и, очевидно, я не могу избежать его использования, так как это решение по дизайну старой библиотеки, которую я использую); я спрашиваю, почему анализатор кода Matlab жалуется на

if(foo==bar)
    GLOBAL baz
    baz=1;
else
    do_other_stuff;
end

но не о

GLOBAL baz
if(foo==bar)
    baz=1;
else
    do_other_stuff;
end

Мне трудно представить причину, по которой первое должно быть медленнее, чем второе.

4 ответа

Решение

Ответ Уолтера Роберсона здесь http://mathworks.com/matlabcentral/answers/19316-global-could-be-very-inefficient

[...] Это не обязательно большая работа, если она не выполняется в команде верхнего уровня, но люди склонны помещать конструкцию в цикл или в несколько неисключительных мест в условных структурах. Человеку, пишущему мельничные предупреждения, гораздо проще не добавлять пояснения вроде: "Если вы не докажете, что эти" глобальные "будут выполняться только один раз, в этом случае это не менее эффективно, но все равно является плохой формой"

поддерживает мой вариант (1).

В дополнение к сообщению эйканала, эта техническая заметка объясняет, почему глобальный процесс медленный.

... когда вызов функции включает в себя глобальные переменные, производительность еще более снижается. Это связано с тем, что для поиска глобальных переменных MATLAB должен расширить свое пространство поиска за пределы текущего рабочего пространства. Более того, причина, по которой вызов функции с глобальными переменными выглядит намного медленнее, чем у других, заключается в том, что MATLAB Accelerator не оптимизирует такой вызов функции.

Я не знаю ответа, но я сильно подозреваю, что это связано с тем, как память выделяется и распределяется во время выполнения.

Как бы то ни было, я рекомендую прочитать следующие две записи в блогах Mathworks Лорен и Дуга:

  1. Написание развертываемого кода, самое первое, что он пишет в этом посте
  2. Лучшие 10 практик кода MATLAB, которые заставляют меня плакать, #2 в этом списке.

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

Факт (с Matlab 2014 до Matlab 2016a, без использования набора инструментов Parallell): часто самым быстрым кодом, который вы можете получить с помощью Matlab, является выполнение вложенных функций, совместное использование переменных между функциями без их передачи.

Шаг, близкий к этому, - использование глобальных переменных и разбиение вашего проекта на несколько файлов. Это может немного снизить производительность, потому что (предположительно, хотя я никогда не видел, чтобы это проверялось ни в одном тесте), Matlab переносит накладные расходы, извлекая из глобального рабочего пространства, и потому, что существует какая-то проблема (предположительно, хотя я никогда не видел никаких доказательств этого)) с ускорением JIT.

Благодаря моему собственному тестированию передача очень больших матриц данных (изображений высокого разрешения) между вызовами функций с использованием вложенных функций или глобальных переменных практически идентична по производительности.

Причина того, что вы можете добиться превосходной производительности с помощью глобальных переменных или вложенных функций, заключается в том, что вы можете избежать копирования дополнительных данных таким образом. Если вы отправляете переменную в функцию, Matlab делает это по ссылке, но если вы изменяете переменную в функции, Matlab делает копию на лету (копирование при записи). Я не знаю, как избежать этого в Matlab, кроме как с помощью вложенных функций и глобальных переменных. Любая небольшая утечка, которую вы получаете от помех к JIT или глобальному времени выборки, полностью достигается за счет избежания этого дополнительного копирования данных (при использовании больших данных).

Это, возможно, изменилось с никогда не версиями Matlab, но из того, что я слышу от друзей, я сомневаюсь в этом. Я не могу сдать ни одного теста, у меня больше нет лицензии Matlab.

В качестве доказательства, посмотрите не дальше, чем этот набор инструментов для обработки видео, который я создал еще в тот день, когда работал с Matlab. Это ужасно уродливо под капотом, потому что у меня не было способа получить производительность без глобалов.

Тот факт, что Matlab (глобальные переменные являются наиболее оптимизированным способом кодирования, когда вам необходимо изменить большие данные в различных функциях), указывает на необходимость обновления языка и / или интерпретатора.

Вместо этого Matlab мог бы использовать лучшее, более динамичное понятие рабочего пространства. Но ничто из того, что я видел, не указывает на то, что это когда-нибудь случится. Особенно, когда вы видите, что сообщество пользователей, по-видимому, игнорирует факты и выдвигает противоположности безо всякой основы: например, использование глобалов в Matlab идет медленно.

Они не.

Тем не менее, вы не должны использовать глобалы, никогда. Если вы вынуждены выполнять обработку видео в реальном времени в чистом Matlab, и вы обнаружите, что у вас нет другого выбора, кроме использования глобалов для достижения производительности, вы должны получить подсказку и сменить язык. Пришло время перейти к языкам с более высокой производительностью... а также, возможно, написать случайные разглагольствования о переполнении стека, в надежде, что Matlab может быть улучшен за счет влияния на мнение своих пользователей.

Другие вопросы по тегам