UE4 — Объект имеет отражение — зачем тогда использовать C++?

Я всегда думал, что UE быстрее, чем Unity, поскольку UE использует C++ и Unity C#. Философия С++, похоже, здесь нарушена, и вы платите за то, что используете. Теперь добавлено отражение и сборка мусора. Так почему же UE4 должен быть быстрее, если они сделали из C++ еще один C#?


person Narek    schedule 29.11.2015    source источник
comment
Отражение не очень затратно с точки зрения высокоуровневых объектов, и скорость C++ по сравнению с C# не сводится просто к отражению. Во многом это связано с распределением памяти, например. Тем не менее, только с точки зрения отражения, UE 4 не использует его, скажем, для UDT самого низкого уровня. Это по-прежнему своего рода плата за то, что вы используете — они не добавляют ее к каждому отдельному struct/class во всей системе.   -  person    schedule 29.11.2015
comment
Возможно, в широком смысле, C++ по-прежнему позволяет вам переходить к самому низкоуровневому виду кода в стиле C - последовательному/фиксированному распределителю памяти, просто работающему с необработанными фрагментами битов и байтов, например. UDT могут размещаться непрерывно, даже если они не выделяются все сразу. Эти высокоуровневые интерфейсы в стиле ECS часто не являются наиболее критичными для производительности частями — это те узкие циклы, относительно небольшой раздел кодовой базы, где мы выигрываем от детализации до настроенного нативного кода самого низкого уровня.   -  person    schedule 29.11.2015
comment
Тогда это может привести к следующему: почему бы не взять C# и не реализовать небольшие критически важные для производительности части на C++? И это может быть вполне законной стратегией — один язык для производительности, другой для производительности. Сложность заключается в том, что, несмотря на то, что разделы, критически важные для производительности, небольшие, часто бывает немного проще сделать все это на одном языке... взять что-то вроде C++ и добавить такие понятия, как свойства, которые можно запрашивать с помощью отражения, тем не менее возможность избежать таких затрат для критических областей ... по сравнению с использованием языка, который имеет это единообразно, и искать скорость на другом языке.   -  person    schedule 29.11.2015


Ответы (1)


Я не уверен, что это полный ответ, я попытался показать, почему и отражение Unreals, и его GC не означают, что он должен быть таким же медленным, как C#.

Отражение

C# имеет очень мощную систему отражения, которая позволяет вам делать множество сумасшедших вещей во время выполнения (создание универсальных классов, генерирующие функции). Это связано с тем, что C# скомпилирован в байтовый код, который представляет собой JIT-код, скомпилированный в исполняемый машинный код. Большая часть отражения реализована в общеязыковом интерфейсе (CLI)1. Это происходит за счет скорости - код должен компилироваться во время выполнения и, как результат, может подвергаться менее агрессивным оптимизациям (меньше времени на их выполнение, поскольку пользователь ожидает запуска программы).

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

Вывоз мусора

Я не знаю деталей системы Unreals Garbage Collection, поэтому этот раздел может быть неполным. Как правило, причина, по которой разработчики игр заботятся о GC (или его отсутствии), заключается в следующем:

  • Языки с GC могут быть расточительны, если у вас много быстрых выделений/освобождений2. В C++ вы можете размещать в стеке (что быстрее3), когда вы знаете, что данные скоро будут выброшены.
  • Вы (разработчик) не знаете, когда сработает GC, что может привести к нарушению плавной частоты кадров. Обычно разработчики предпочитают контролировать, когда происходит сборка мусора.

Unreal может избежать первой проблемы, так как в любом случае только UObject GC'ируются. Это означает, что вы по-прежнему можете использовать обычные классы, не беспокоясь о сборщике мусора, и с удовольствием выделять память в стеке, когда это необходимо.

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


В заключение, Unreal по-прежнему может использовать функции, которые позволяют C++ быть быстрее, чем C# (более агрессивная оптимизация, выделение стека) даже с базовой версией отражения и GC, которые у него есть.

1: Как реализовано отражение в C#?

2: Примеры расточительного выделения кучи

3: Что быстрее: выделение стека или выделение кучи

person T. Kiley    schedule 30.11.2015