Unreal Engine - многопоточность в Blueprint

Чтобы разблокировать силу многопоточности (и скорее всего силу земли) достаточно простого советского...

Зачем

  • Разгрузить основной поток, сбрагрив часть нагрузки на другие рабочие потоки
  • Сгладить возможные фризы/просадки FPS
  • Флексить умением работы с многопоточностью в резюме/перед коллегами

Собственно код

Достаточно интегрировать код ниже в любой существующий .h файл проекта или же создать новый .h и скопировать все туда. После этого нужно заменить ThreadTest в последнем include на название файла, в который вы поместили код.

#pragma once #include "CoreMinimal.h" #include "Kismet/BlueprintAsyncActionBase.h" // нужно заменить ThreadTest на название файла, в котором находится этот код #include "ThreadTest.generated.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAsyncDelegate); UCLASS() class UAsyncNode : public UBlueprintAsyncActionBase { GENERATED_BODY() public: // делегат, который вызовется в рабочем потоке UPROPERTY(BlueprintAssignable) FAsyncDelegate Async; // делегат, который вызовется при окончании работы рабочего потока UPROPERTY(BlueprintAssignable) FAsyncDelegate Complete; // название функции будет использоваться в качестве названия блюпринт ноды. Можно переименовать на свое усмотрение UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true")) static UAsyncNode* DoAsync() { UAsyncNode* Node = NewObject<UAsyncNode>(); return Node; }; virtual void Activate() override { AsyncTask(ENamedThreads::AnyThread, [&]() { Async.Broadcast(); AsyncTask(ENamedThreads::GameThread, [&]() { Complete.Broadcast(); SetReadyToDestroy(); }); }); }; };

В общем-то и все, теперь в любом блюпринте проекта можно будет добавить DoAsync ноду с 3 пинами:

Unreal Engine - многопоточность в Blueprint
  1. Безымянный Exec - сработает в основном потоке сразу при активации ноды
  2. Async - сработает в worker потоке
  3. Complete - сработает в основном потоке после завершения исполнения Async

Ограничения

К сожалению, значительная часть кода Unreal может исполняться только в основном потоке (GameThread), например

  • Cоздание UObject'ов (а следовательно Actor'ов, Character'ов и т.д.)
  • Манипуляции с положением объектов в пространстве
  • Поиск всех акторов по классу

За это отвечают щедро рассыпанные по коду IsInGameThread() проверки при провале которых можно словить краш редактора.

Что можно/стоит делать?

  • Тяжелыевычисления
  • Блокирующие API вызовы
  • Чтение/парсинг файлов
  • Обработку списков объектов/акторов, если этот список был уже сформирован в главном потоке
Время наслаждаться плодами оптимизации
Время наслаждаться плодами оптимизации

Делайте хорошие игры. Плохие тоже делайте, а то как иначе учиться. :)

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

4242
88
29 комментариев

Многопоточность в анрил из коробки к концу 2024го планируют завести , емнип

3
Ответить

Это уже и так почти "из коробки", сложно представить, куда дальше
С большой силой приходит и ответсвенность, не получится просто так направо и налево автоматически раздавать исполнение по потокам
Равно как не получится автоматически понять, какой код подойдет для вынесения, а какой - не очень

В целом эпики много чего постоянно завозят, проблема больше в том, что ни поддержи толковой, ни документации от них обычно не дождешься.
Взять тот же UBA, Unreal Build Accelerator. В 5.3 только и разговоров было про него, во всех профильных и не очень изданиях в патчноутах написали, как зажимем-то теперь с ускорением. А по факту как им пользоваться можно было найти только на каком-то рандомном китайском сайте только :D

3
Ответить

Скинь разрабам Хогвартса, они уже год не могут починить проблему того, что игра долбится в 1 ядро и видеокарта простаивает из-за этого.

3
Ответить

Как раз сейчас прохожу, столько бед с оптимизацией, LOD'ами, подгрузками, эх
Производительность нынче не в моде среди разработчиков 🤷‍♂️

2
Ответить

аргумента -numthreads X при запуске недостаточно?

1
Ответить

Нет, т.к. почти все, что есть в блюпринтах исполняется на основном потоке
numthreads только определяет количество доступных worker потоков, сами по себе они ничего делать не будут

1
Ответить

Товарищ, а не подскажете может тогда курсы по БП? Только из разряда не для кодера, а для художника
Хоть платные, хоть бесплатные, хоть английские хоть русские
Ну или хотя бы куда смотреть?

1
Ответить