Equilibrant C++ i Blueprints – Programació general i de joc

frob va dir:
Crec que el millor paral·lel és preguntar-se “quina gota de pluja és responsable de la inundació?” Cada trucada, cada funció, cada node de plànol individualment té un cost. Individualment, el cost del plànol és relativament petit, en qualsevol part de l’ordre des d’uns centenars de nanosegons fins a uns pocs microsegons. Les còpies d’UStructs es fan tot el temps i no són gratuïtes amb assignacions i duplicacions. La gestió de la memòria temporal no és gratuïta. Prenen cicles de CPU, consumeixen espai de memòria cau i generen costos a la memòria principal. No són inherentment dolents, però s’acumulen.

Tot i que no és exactament el que preguntava. “Cada trucada” no els impedeix utilitzar un JIT. “Cada trucada” no fa que la nativització falli. Per descomptat, en un llenguatge interpretat tot té una sobrecàrrega addicional, però escriure Blueprint-Code amb trucades que existeixen en C++ hauria de significar que ha d’estar disponible una forma d’execució més òptima. M’interessava més l’exemple per què ho impedeix o ho dificulta, com tu dius.

frob va dir:
El problema més gran que he tingut en la reestructuració del codi creat pel dissenyador és la seva dependència excessiva massiva d’iterar a través de contenidors o de fer-los de mala manera. Un exemple recent, iterant a través de diversos milers d’objectes, els llança al tipus desitjat i continueu si coincideixen. Un repartiment individual triga poc menys d’un microsegon cadascun. Estaven parlant d’una gran part de cada actualització només intentant esbrinar si un objecte era l’adequat per continuar el processament.

Per tant, part del problema amb els plànols que utilitzen els dissenyadors són les males opcions algorítmiques amb un alt ordre de magnitud d’iteracions. Suposo que almenys té sentit, i suposo que en alguns casos estem parlant de coses tan mal escrites que, encara que s’executin de manera nativa, no seria viable en producció?

Tot i que aquest no és un punt que els impedeixi proporcionar un backend (relativament) més eficaç amb un cost més baix. Es poden escriure algorismes dolents en C# sense haver de duplicar amb el codi que no s’executa de manera nativa. No estic segur de si em perdo alguna cosa o si no he pogut comunicar el que volia dir de manera eficaç. Així que per mostrar què vull dir, he fet una prova ràpida tant a Unreals com als meus propis “plans”.

Això triga uns 0,534 segons a executar-se, bastant dolent per a un bucle tan petit, ni tan sols es pot utilitzar índexs més alts o detectarà un bucle infinit.

Aquest és el mateix codi al meu propi motor. Espereu que faci perfils externament, però la sobrecàrrega principal aquí hauria de ser el bucle de totes maneres. Aquesta funció. compilat amb un JIT, triga 0,011 s. Això és gairebé x50 més ràpid! Aquest és el meu punt. No hi ha cap raó perquè un llenguatge de programació visual hagi de ser tan lent. Les mateixes coses sobre com l’utilitzen els artistes sense experiència s’aplicarien al meu llenguatge que als plànols. Però, sense forçar una eina de nativització (aparentment) trencada, sinó simplement utilitzant (fins i tot un compilador molt ximple) JIT, voldria dir que si tinguéssiu un exemple en què un arist fes un bucle de més de 1000 elements a UE-Blueprint i era massa lent, amb un millor backend podria haver estat gairebé insignificant.

Això fa que el meu punt sigui més clar? Òbviament, hi ha alguna cosa que fa que els Blueprints siguin lents, però no té res a veure amb la manera com es presenta la interfície d’usuari, perquè aleshores el meu propi exemple seria igual de lent, que ni tan sols està a prop.

EDITAR:
Per a més informació, el mateix codi en C++ (al meu motor) fa el següent:

core::Timer	timer;
int x = 0;
for (int i = 0; i < 200000; i++)
{
	x = x + sys::Random::Max(1);
}

const auto duration = timer.Duration();
core::Log::OutInfoFmt("Took {}s", duration);

return x;

Depuració: 0,025 s
Emissió: 0,005 s

Per tant, el meu JIT supera el codi Debug-c++ per un factor de 2x en aquest moment (probablement ja que utilitza un format més òptim per a l'ASM generat, que és més semblant a com ho faria un optimitzador), mentre que el codi c++ optimitzat és d'aproximadament 2 vegades més ràpid que el meu JIT (amb la diferència és 5 vegades entre el llançament de depuració en aquest exemple). Això hauria de donar una referència per al rendiment relatiu del meu sistema, així com il·lustrar encara més el punt que el projecte no està obligat a ser lent pel fet de com es connecta, sinó com s'integra el seu backend.

.

Leave a Comment

Your email address will not be published. Required fields are marked *