А как насчет нестабильности типов так сильно вредит производительности? - PullRequest
6 голосов
/ 27 сентября 2019

Мне любопытно, если у вас в коде нестабильность типа, что именно так сильно влияет на производительность?

  • Это буквально проверка типов, которую нужно выполнять во время выполнениячто я представляю себе в голове кучу операторов if / else (если Float64 ... elseif Int64 elseif Float32 ... etc)
  • И / или проверка типов не позволяет конвейеру ЦП конвейеризоватьдля циклов?
  • Или это основная проблема выделения кучи, которое происходит для всех операций с переменными нестабильного типа?
  • Или что-то еще?
  • Буду признателен за любые идеи или ссылки на дополнительные ресурсы.

Этот вопрос был первоначально задан Оскаром на Джулиан Лэнг Slack Channel

1 Ответ

5 голосов
/ 27 сентября 2019

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

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

Однако в Julia 1.x компилятор может выполнить «оптимизацию небольшого объединения», что означает, что если компилятор определяет, чтозначение должно быть одним небольшим числом конкретных типов (в настоящее время ≤ 4), тогда вместо динамической отправки он может проверить, является ли фактический тип какой-либо из этих четырех возможностей, и сгенерировать ветку, в которой конкретный тип значения равенизвестной и динамичной отправки можно полностью избежать.Например, если значение может быть Int или nothing, то компилятор может проверить, является ли оно nothing, и обработать этот случай, в противном случае он знает, что значение должно быть Int, и он может сгенерировать эффективный код для этого.кейс тоже.

...