This commit is contained in:
2026-01-05 15:02:44 +02:00
parent 8561d28642
commit 856be55132
6 changed files with 520 additions and 169 deletions

View File

@@ -1,7 +1,7 @@
{
"ID": "2a86c77242441f5ac25b4a8bbf4029a8",
"TypeName": "FlaxEngine.SceneAsset",
"EngineBuild": 6804,
"EngineBuild": 6805,
"Data": [
{
"ID": "2a86c77242441f5ac25b4a8bbf4029a8",
@@ -26,7 +26,9 @@
"ID": "efa3263d4596af098d5babb8fd6ea6fb",
"TypeName": "Game.MyScriptTwo",
"ParentID": "2a86c77242441f5ac25b4a8bbf4029a8",
"V": {}
"V": {
"Model": "50310067422bada39f9553b41c4869a4"
}
}
]
}

View File

@@ -27,7 +27,13 @@ public class Game : GameModule
public override void Setup(BuildOptions options)
{
options.ScriptingAPI.IgnoreMissingDocumentationWarnings = true;
//options.CompileEnv.PreprocessorDefinitions.Add("COMPILE_WITH_CSG_BUILDER");
options.ScriptingAPI.IgnoreSpecificWarnings.Add("CS9191"); // ref with in parameters
options.ScriptingAPI.IgnoreSpecificWarnings.Add("CS1717"); // assignment with itself
options.ScriptingAPI.IgnoreSpecificWarnings.Add("CS0219"); // assignment unused
options.ScriptingAPI.IgnoreSpecificWarnings.Add("CS0414"); // assignment unused
options.ScriptingAPI.IgnoreSpecificWarnings.Add("CS0649"); // default value assignment
options.CompileEnv.PreprocessorDefinitions.Add("COMPILE_WITH_CSG_BUILDER");
//options.PublicDefinitions.Add("COMPILE_WITH_CSG_BUILDER");
base.Setup(options);
@@ -35,6 +41,8 @@ public class Game : GameModule
//Tags["Network"] = string.Empty;
//options.PublicDependencies.Add("Networking");
//options.PublicDependencies.Add("FidelityFXFSR");
//options.ScriptingAPI.FileReferences.Add(Path.Combine(Globals.EngineRoot, "Source", "Platforms", "DotNet", "Newtonsoft.Json.dll"));
@@ -50,7 +58,7 @@ public class Game : GameModule
options.ScriptingAPI.Defines.Add("COMPILE_WITH_FSR1");
#endif
options.PublicDependencies.Add("OnlinePlatformSteam");
//options.PublicDependencies.Add("OnlinePlatformSteam");
// Here you can modify the build options for your game module
// To reference another module use: options.PublicDependencies.Add("Audio");
// To add C++ define use: options.PublicDefinitions.Add("COMPILE_WITH_FLAX");

View File

@@ -13,7 +13,12 @@
#include "Engine/Core/Collections/Sorting.h"
#include "Engine/Render2D/FontAsset.h"
#define NEW_VERSION 1
#define NEW_VERSION 0
#define TRACK_GCHANDLE_ALLOCS 1
#if NEW_VERSION
#define TRACK_GCHANDLE_ALLOCS 1
#endif
#if BUILD_DEBUG
#define LONGER 3
@@ -43,6 +48,139 @@ MyScript::MyScript(const SpawnParams& params)
}
double t95(int n) { return 1.96 + 2.4 / (n - 1.0); }
template<typename... TArgs>
void MyScript::BenchmarkCall(BenchmarkContext& context, void(MyScript2::* fun)(TArgs...),
TArgs... args)
{
long totalTimes = 0;
auto chunkTimes = CHUNK_TIMES;
const auto cycleTimes = 1 * LONGER;
const double minTime = 200;
const double maxMaxTime = 5000;
double maxTime = maxMaxTime;
const auto freq = Platform::GetClockFrequency();
context.results.Clear();
uint64 bestResult = UINT64_MAX;
{
auto start0 = Platform::GetTimeCycles();
for (int i = 0; i < 10; ++i)
(*context.scriptTwo.*fun)(args...);
auto end0 = Platform::GetTimeCycles();
auto elapsed0 = end0 - start0;
auto elapsed0ns = (elapsed0 * (1.0 / static_cast<double>(freq)) * 1000000000);
if (elapsed0 > 100000)
chunkTimes = CHUNK_TIMES / 50;
else if (elapsed0 > 80000)
chunkTimes = CHUNK_TIMES / 40;
else if (elapsed0 > 60000)
chunkTimes = CHUNK_TIMES / 30;
else if (elapsed0 > 30000)
chunkTimes = CHUNK_TIMES / 20;
else if (elapsed0 > 20000)
chunkTimes = CHUNK_TIMES / 10;
else if (elapsed0 > 10000)
chunkTimes = CHUNK_TIMES / 5;
else if (elapsed0 > 5000)
chunkTimes = CHUNK_TIMES / 2;
/*if (chunkTimes != CHUNK_TIMES)
LOG(Info, " - chunk times adjusted to {} (elapsed {})", chunkTimes, elapsed0);
else
LOG(Info, " - elapsed {}", elapsed0);*/
}
auto start1 = Platform::GetTimeCycles();
uint64 totaccum = 0;
while (true)
{
uint64 previousBest = bestResult;
uint64 currentBest = UINT64_MAX;
auto start2 = Platform::GetTimeCycles();
for (int i = 0; i < cycleTimes; ++i)
{
auto start = Platform::GetTimeCycles();
for (int j = 0; j < chunkTimes; ++j)
(*context.scriptTwo.*fun)(args...);
auto end = Platform::GetTimeCycles();
auto elapsed = end - start;
if (elapsed < currentBest)
currentBest = elapsed;
context.results.Add(elapsed);
totaccum += elapsed;
}
auto end2 = Platform::GetTimeCycles();
auto elapsed2 = end2 - start2;
auto elapsed2Ms = (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000);
//Sorting::MergeSort(context.results);
totalTimes += cycleTimes * chunkTimes;
if (currentBest < bestResult)
bestResult = currentBest;
auto elapsed1 = Platform::GetTimeCycles() - start1;
auto elapsedMs = (elapsed1 * (1.0 / static_cast<double>(freq)) * 1000);
if (elapsedMs < minTime)
continue;
if (context.results.Count() > 20)
{
double avg = (double)totaccum / context.results.Count();
//avg = (avg * (1.0 / static_cast<double>(freq)) * 1000000000);
double stdev = 0;
{
auto n = context.results.Count();
double s = 0.0;
for (int i = 0; i < n; ++i) {
//double d = (context.results[i] * (1.0 / static_cast<double>(freq)) * 1000000000);
double d = (double)context.results[i];
d = d - avg;
s += d * d;
}
stdev = sqrt(s / (n - 1));
}
double ci = t95(context.results.Count()) * stdev / sqrt((double)context.results.Count());
double rel = (ci / avg) * 100;
if (rel < 1.0)
break;
}
if (elapsedMs >= maxTime)
break;
}
double avg = (double)totaccum / context.results.Count();
avg = (avg * (1.0 / static_cast<double>(freq)) * 1000000000);
double stdev = 0;
{
auto n = context.results.Count();
double s = 0.0;
for (int i = 0; i < n; ++i) {
double d = (context.results[i] * (1.0 / static_cast<double>(freq)) * 1000000000);
d = d - avg;
s += d * d;
}
stdev = sqrt(s / (n - 1));
}
double ci = t95(context.results.Count()) * stdev / sqrt((double)context.results.Count());
double rel = (ci / avg) * 100;
ci /= chunkTimes;
stdev /= chunkTimes;
avg /= chunkTimes;
auto elapsed1 = Platform::GetTimeCycles() - start1;
const auto bestResultNs = (bestResult * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes);
LOG(Info, " - VirtualCall: {:.1f}ns +-{:.1f}ns, std:{:.1f}ns, {:.1f}%, avg:{:.1f} ({:.0f}ms/{})", bestResultNs, ci, stdev, rel, avg, (elapsed1 * (1.0 / static_cast<double>(freq)) * 1000), totalTimes, ci);
}
void MyScript::OnStart()
{
LOG(Info, "C++ OnStart");
@@ -50,8 +188,9 @@ void MyScript::OnStart()
if (scriptTwo == nullptr)
return;
bool callTests = true;
bool thunkTests = false;
bool invokeTests = true;
bool invokeTests = false; // requires manual type conversion
bool coverageTests = false;
bool otherTests = true;
@@ -73,7 +212,12 @@ void MyScript::OnStart()
Array<Actor*> actorArray; for (int i=0; i<10; i++) actorArray.Add(actor);
TestStruct testStruct; testStruct.Object = actor; testStruct.SceneRef = sceneRef;
Array<TestStruct> complexArray; for (int i=0; i<10; i++) complexArray.Add(testStruct);
StringStruct stringStruct;
Array<StringStruct> stringStructArray; for (int i = 0; i < 10; i++) stringStructArray.Add(stringStruct);
BenchmarkContext benchmarkContext;
benchmarkContext.scriptTwo = scriptTwo;
benchmarkContext.results = results;
// Coverage
if (coverageTests)
@@ -96,20 +240,35 @@ void MyScript::OnStart()
Array<StringAnsi> ansiStrings(&shortStringAnsi, 1);
Array<Float3> float3s(&f3, 1);
Array<ModelLOD*> lods(&lod, 1);
BytesContainer bytes;
bytes.Append((byte*)&f3, sizeof(Float3));
BytesContainer bytesOut;
COVERAGE_CALL_ARGS6(CoverageTest1, integer, boolean, actor, shortString, shortStringAnsi, f3);
COVERAGE_CALL_ARGS6(CoverageTest1Array, ints, booleans, actors, strings, ansiStrings, float3s);
COVERAGE_CALL_ARGS5(CoverageTest1ByRef, integer, boolean/*, actor*/, shortString, shortStringAnsi, f3);
COVERAGE_CALL_ARGS5(CoverageTest1ArrayByRef, ints, booleans/*, actors*/, strings, ansiStrings, float3s);
//COVERAGE_CALL_ARGS5(CoverageTest1ArrayByRef, ints, booleans/*, actors*/, strings, ansiStrings, float3s);
COVERAGE_CALL_ARGS4(CoverageTest2, fontAssetGuid, fontAssetRef, Array<Guid>(&fontAssetGuid, 1), Array<AssetReference<FontAsset>>(&fontAssetRef, 1));
COVERAGE_CALL_ARGS2(CoverageTest3, lod, lods);
//COVERAGE_CALL_ARGS2(CoverageTest4, bytes, bytesOut);
COVERAGE_CALL_ARGS6(CoverageNamespaces1, networkChannelType, Array<NetworkChannelType>(&networkChannelType, 1), onlineLeaderboardSortModes, Array<OnlineLeaderboardSortModes>(&onlineLeaderboardSortModes, 1), onlineLeaderboardValueFormats, Array<OnlineLeaderboardValueFormats>(&onlineLeaderboardValueFormats, 1));
scriptTwo->ManagedCoverageTests();
}
#if NEW_VERSION
// Warmup busy-loop
{
const auto freq = Platform::GetClockFrequency();
auto startt = Platform::GetTimeCycles();
auto elapsedMs = ((Platform::GetTimeCycles() - startt) * (1.0 / static_cast<double>(freq)) * 1000);
while (elapsedMs > 2000)
{
elapsedMs = ((Platform::GetTimeCycles() - startt) * (1.0 / static_cast<double>(freq)) * 1000);
}
}
#if TRACK_GCHANDLE_ALLOCS
int64 allocationsBefore, deallocationsBefore;
scriptTwo->GetStats(allocationsBefore, deallocationsBefore);
#endif
@@ -117,13 +276,18 @@ void MyScript::OnStart()
if (otherTests)
{
LOG_TEST(SimpleCall);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::SimpleCall);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS0(TIMES2, SimpleCall);
BENCHMARK_THUNK_BEGIN_ARGS0(TIMES2, SimpleCall);
BENCHMARK_THUNK_CALL_ARGS0();
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS0(TIMES2, SimpleCall);
@@ -133,9 +297,12 @@ void MyScript::OnStart()
if (otherTests)
{
LOG_TEST(SimpleParams);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::SimpleParams, (int32)1, (float)2, '3', (double)4, (int64)5);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS5(TIMES4, SimpleParams, 1, 2, '3', 4, 5);
BENCHMARK_THUNK_BEGIN_ARGS5(TIMES3, SimpleParams);
params[0] = MUtils::Box<int>(1, MCore::TypeCache::Int32);
params[1] = MUtils::Box<float>(2, MCore::TypeCache::Single);
@@ -157,14 +324,60 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
//#if NEW_VERSION
/*BENCHMARK_INVOKE_ARGS5(TIMES3, SimpleParams,
(int32)1,
(float)2,
(char)'3',
(double)4,
(int64)5);*/
//#else
int32 a = 1;
float b = 2;
char c = 3;
double d = 4;
int64 e = 5;
BENCHMARK_INVOKE_ARGS5(TIMES3, SimpleParams,
MUtils::Box<int>(1, MCore::TypeCache::Int32),
MUtils::Box<float>(2, MCore::TypeCache::Single),
MUtils::Box<char>('3', MCore::TypeCache::SByte),
MUtils::Box<double>(4, MCore::TypeCache::Double),
MUtils::Box<long>(5, MCore::TypeCache::Int64));
(void*)&a,
(void*)&b,
(void*)&c,
(void*)&d,
(void*)&e);
//#endif
/*void* params[5];
{
auto klass = MyScript2::GetStaticClass();
auto method = klass->GetMethod("SimpleParams", 5);
auto instance = scriptTwo->GetManagedInstance();
MObject* exception = nullptr;
const auto times = (100 * 3);
const auto chunkTimes = 100;
const auto freq = Platform::GetClockFrequency();
params[0] = MUtils::Box<int32>(1, MCore::TypeCache::Int32);
params[1] = MUtils::Box<float>(2, MCore::TypeCache::Single);
params[2] = MUtils::Box<char>('3', MCore::TypeCache::SByte);
params[3] = MUtils::Box<double>(4, MCore::TypeCache::Double);
params[4] = MUtils::Box<int64>(5, MCore::TypeCache::Int64);
results.Clear();
auto start2 = Platform::GetTimeCycles();
for (int i = 0; i < times; ++i)
{
auto start = Platform::GetTimeCycles();
for (int j = 0; j < chunkTimes; ++j) method->Invoke(instance, params, &exception);
auto end = Platform::GetTimeCycles();
auto elapsed = end - start;
results.Add(elapsed);
}
auto end2 = Platform::GetTimeCycles();
auto elapsed2 = end2 - start2;
Sorting::MergeSort(results);
const auto resultsIndex = 0;
Log::Logger::Write(LogType::Info, ::String::Format(L" - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times * chunkTimes));
};*/
#if NEW_VERSION
auto __param0_handle = *(MGCHandle*)&params[0];
MCore::GCHandle::Free(__param0_handle);
@@ -184,9 +397,12 @@ void MyScript::OnStart()
if (otherTests)
{
LOG_TEST(StringParamAnsi);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::StringParamAnsi, shortStringAnsi);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES3, StringParamAnsi, shortStringAnsi);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, StringParamAnsi);
params[0] = MUtils::Box<StringAnsi>(shortStringAnsi, MCore::TypeCache::String);
BENCHMARK_THUNK_CALL_ARGS1();
@@ -195,6 +411,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamAnsi,
@@ -207,9 +425,12 @@ void MyScript::OnStart()
if (otherTests)
{
LOG_TEST(StringParam);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::StringParam, shortString);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES3, StringParam, shortString);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, StringParam);
params[0] = MUtils::Box<String>(shortString, MCore::TypeCache::String);
BENCHMARK_THUNK_CALL_ARGS1();
@@ -218,6 +439,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParam,
@@ -227,12 +450,16 @@ void MyScript::OnStart()
#endif
}
}
#if false
if (otherTests)
{
LOG_TEST(StringParamRef);
if (callTests)
{
BenchmarkCall(&MyScript2::StringParamRef, shortString);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES3, StringParamRef, shortString);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, StringParamRef);
params[0] = MUtils::Box<String>(shortString, MCore::TypeCache::String);
BENCHMARK_THUNK_CALL_ARGS1();
@@ -241,6 +468,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamRef,
@@ -250,12 +479,16 @@ void MyScript::OnStart()
#endif
}
}
#endif
if (otherTests)
{
LOG_TEST(StringParamRefConst);
if (callTests)
{
BenchmarkCall<const String&>(benchmarkContext, &MyScript2::StringParamRefConst, shortString);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES3, StringParamRefConst, shortString);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, StringParamRefConst);
params[0] = MUtils::Box<String>(shortString, MCore::TypeCache::String);
BENCHMARK_THUNK_CALL_ARGS1();
@@ -264,6 +497,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamRefConst,
@@ -276,10 +511,13 @@ void MyScript::OnStart()
if (asRefTests)
{
LOG_TEST(StringParamAsRef);
if (thunkTests)
if (callTests)
{
String str = shortString;
BENCHMARK_CALL_ARGS1_REF(TIMES3, StringParamAsRef, str);
BenchmarkCall<String&>(benchmarkContext, &MyScript2::StringParamAsRef, str);
}
if (thunkTests)
{
LOG(Info, " - InvokeThunkOnly: not valid");
/* str = shortString;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, StringParamAsRef);
@@ -301,12 +539,20 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();*/
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
String str = shortString;
#if NEW_VERSION
BENCHMARK_INVOKE_ARGS1_REF(TIMES3, StringParamAsRef,
MUtils::Box<String>(str, MCore::TypeCache::String),
MUtils::Box<String>(shortString, MCore::TypeCache::String),
MUtils::FreeManaged<String>);
#else
BENCHMARK_INVOKE_ARGS1_REF(TIMES3, StringParamAsRef,
MUtils::Box<String>(shortString, MCore::TypeCache::String),
{});
#endif
}
}
@@ -314,14 +560,19 @@ void MyScript::OnStart()
if (otherTests)
{
LOG_TEST(ActorParam);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::ActorParam, actor);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES2, ActorParam, actor);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, ActorParam);
params[0] = ScriptingObject::ToManaged((ScriptingObject*)actor);
BENCHMARK_THUNK_CALL_ARGS1();
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, ActorParam,
@@ -333,9 +584,12 @@ void MyScript::OnStart()
if (otherTests)
{
LOG_TEST(ComplexParam);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::ComplexParam, behaviorUpdateContext);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES3, ComplexParam, behaviorUpdateContext);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, ComplexParam);
params[0] = MUtils::Box<BehaviorUpdateContext>(behaviorUpdateContext, BehaviorUpdateContext::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
@@ -344,23 +598,53 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, ComplexParam,
MUtils::Box<BehaviorUpdateContext>(behaviorUpdateContext, BehaviorUpdateContext::TypeInitializer.GetClass()));
//auto param1 = MUtils::Box<BehaviorUpdateContext>(behaviorUpdateContext, BehaviorUpdateContext::TypeInitializer.GetClass());
/*void* params[1];
{
auto klass = MyScript2::GetStaticClass();
auto method = klass->GetMethod("ComplexParam", 1);
auto instance = scriptTwo->GetManagedInstance();
MObject* exception = nullptr;
const auto times = (1000 * 3);
const auto chunkTimes = 100;
const auto freq = Platform::GetClockFrequency();
params[0] = &behaviorUpdateContext;
results.Clear();
auto start2 = Platform::GetTimeCycles();
for (int i = 0; i < times; ++i) {
auto start = Platform::GetTimeCycles();
for (int j = 0; j < chunkTimes; ++j) method->Invoke(instance, params, &exception);
auto end = Platform::GetTimeCycles();
auto elapsed = end - start;
results.Add(elapsed);
}
auto end2 = Platform::GetTimeCycles();
auto elapsed2 = end2 - start2;
Sorting::MergeSort(results);
const auto resultsIndex = 0;
Log::Logger::Write(LogType::Info, ::String::Format(L" - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times * chunkTimes));
};*/
BENCHMARK_INVOKE_ARGS1(TIMES2, ComplexParam, &behaviorUpdateContext);
#if NEW_VERSION
MUtils::FreeManaged<BehaviorUpdateContext>((MObject*)params[0]);
//MUtils::FreeManaged<BehaviorUpdateContext>((MObject*)params[0]);
#endif
}
}
if (otherTests)
{
LOG_TEST(Complex2Param);
if (callTests)
{
BenchmarkCall<RenderContext&>(benchmarkContext, &MyScript2::Complex2Param, renderContext);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, Complex2Param, renderContext);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2Param);
params[0] = MUtils::Box<RenderContext>(renderContext, RenderContext::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
@@ -369,21 +653,25 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2Param,
MUtils::Box<RenderContext>(renderContext, RenderContext::TypeInitializer.GetClass()));
BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2Param, &renderContext);
#if NEW_VERSION
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
//MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
#endif
}
}
if (otherTests)
{
LOG_TEST(Complex2ParamConst);
if (callTests)
{
BenchmarkCall<const RenderContext&>(benchmarkContext, &MyScript2::Complex2ParamConst, renderContext);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, Complex2ParamConst, renderContext);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2ParamConst);
params[0] = MUtils::Box<RenderContext>(renderContext, RenderContext::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
@@ -392,22 +680,26 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2ParamConst,
MUtils::Box<RenderContext>(renderContext, RenderContext::TypeInitializer.GetClass()));
BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2ParamConst, &renderContext);
#if NEW_VERSION
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
//MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
#endif
}
}
if (asRefTests)
{
LOG_TEST(Complex2ParamAsRef);
if (thunkTests)
if (callTests)
{
RenderContext context = renderContext;
BENCHMARK_CALL_ARGS1_REF(TIMES4, Complex2ParamAsRef, context);
BenchmarkCall<RenderContext&>(benchmarkContext, &MyScript2::Complex2ParamAsRef, context);
}
if (thunkTests)
{
LOG(Info, " - InvokeThunkOnly: not valid");
/* context = renderContext;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2ParamAsRef);
@@ -431,15 +723,20 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();*/
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
}
if (arrayTests)
{
LOG_TEST(SimpleArrayParam);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::SimpleArrayParam, simpleArray);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, SimpleArrayParam, simpleArray);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, SimpleArrayParam);
params[0] = MUtils::ToArray(simpleArray, MCore::TypeCache::Int32);
BENCHMARK_THUNK_CALL_ARGS1();
@@ -448,6 +745,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, SimpleArrayParam,
@@ -460,10 +759,13 @@ void MyScript::OnStart()
if (arrayTests && asRefTests)
{
LOG_TEST(SimpleArrayParamAsRef);
if (thunkTests)
if (callTests)
{
Array<int> arr = simpleArray;
BENCHMARK_CALL_ARGS1_REF(TIMES4, SimpleArrayParamAsRef, simpleArray);
BenchmarkCall<Array<int32>&>(benchmarkContext, &MyScript2::SimpleArrayParamAsRef, simpleArray);
}
if (thunkTests)
{
LOG(Info, " - InvokeThunkOnly: not valid");
/* arr = simpleArray;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, SimpleArrayParamAsRef);
@@ -486,15 +788,20 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();*/
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
}
if (arrayTests)
{
LOG_TEST(ActorArrayParam);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::ActorArrayParam, actorArray);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, ActorArrayParam, actorArray);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, ActorArrayParam);
params[0] = MUtils::ToArray(actorArray, Actor::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
@@ -503,6 +810,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, ActorArrayParam,
@@ -513,12 +822,49 @@ void MyScript::OnStart()
}
}
if (otherTests)
{
LOG_TEST(StringFieldStructParam);
if (callTests)
{
BenchmarkCall<StringStruct&>(benchmarkContext, &MyScript2::StringFieldStructParam, stringStruct);
}
}
if (otherTests && asRefTests)
{
LOG_TEST(StringFieldStructParamAsRef);
if (callTests)
{
StringStruct ss = stringStruct;
BenchmarkCall<StringStruct&>(benchmarkContext, &MyScript2::StringFieldStructParamAsRef, ss);
}
}
if (arrayTests)
{
LOG_TEST(StringFieldStructArrayParam);
if (callTests)
{
BenchmarkCall<Array<StringStruct>&>(benchmarkContext, &MyScript2::StringFieldStructArrayParam, stringStructArray);
}
}
if (arrayTests && asRefTests)
{
LOG_TEST(StringFieldStructArrayParamAsRef);
if (callTests)
{
Array<StringStruct> arr = stringStructArray;
BenchmarkCall<Array<StringStruct>&>(benchmarkContext, &MyScript2::StringFieldStructArrayParamAsRef, arr);
}
}
if (arrayTests)
{
LOG_TEST(ComplexArrayParam);
if (callTests)
{
BenchmarkCall(benchmarkContext, &MyScript2::ComplexArrayParam, complexArray);
}
if (thunkTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, ComplexArrayParam, complexArray);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, ComplexArrayParam);
params[0] = MUtils::ToArray(complexArray, TestStruct::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
@@ -527,6 +873,8 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, ComplexArrayParam,
@@ -539,10 +887,13 @@ void MyScript::OnStart()
if (arrayTests && asRefTests)
{
LOG_TEST(ComplexArrayParamAsRef);
if (thunkTests)
if (callTests)
{
Array<TestStruct> arr = complexArray;
BENCHMARK_CALL_ARGS1_REF(TIMES4, ComplexArrayParamAsRef, arr);
BenchmarkCall<Array<TestStruct>&>(benchmarkContext, &MyScript2::ComplexArrayParamAsRef, arr);
}
if (thunkTests)
{
LOG(Info, " - InvokeThunkOnly: not valid");
/* arr = complexArray;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES4, ComplexArrayParamAsRef);
@@ -566,9 +917,11 @@ void MyScript::OnStart()
#endif
BENCHMARK_THUNK_END();*/
}
//else
// LOG(Info, " - InvokeThunkOnly: skipped");
}
#if NEW_VERSION
#if TRACK_GCHANDLE_ALLOCS
int64 allocationsAfter, deallocationsAfter;
scriptTwo->GetStats(allocationsAfter, deallocationsAfter);
int64 allocationsDiff = allocationsAfter-allocationsBefore;

View File

@@ -14,6 +14,17 @@
#include "Engine/Online/IOnlinePlatform.h"
#include "Engine/Render2D/FontAsset.h"
API_STRUCT(NoDefault) struct StringStruct : public ISerializable
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE_MINIMAL(StringStruct);
API_FIELD() String StringContent = TEXT("test");
API_FIELD() String StringEmpty = TEXT("");
API_FIELD() String StringEmpty2 = String::Empty;
API_FIELD() String StringNull = nullptr;
};
API_STRUCT(NoDefault) struct TestStruct : public ISerializable
{
API_AUTO_SERIALIZATION();
@@ -45,47 +56,66 @@ API_CLASS() class GAME_API MyScript2 : public Script
API_FUNCTION() virtual void GetStats(API_PARAM(Ref) int64& allocations, API_PARAM(Ref) int64& deallocations) {};
API_FUNCTION() virtual void ManagedCoverageTests() {};
API_FUNCTION() virtual void CoverageTest1(int32 a, bool b, Actor* c, String& d, StringAnsi& e, Float3 f) {};
API_FUNCTION() virtual void CoverageTest1Array(Array<int32> a, Array<bool> b, Array<Actor*> c, Array<String> d, Array<StringAnsi> e, Array<Float3> f) {};
API_FUNCTION() virtual void CoverageTest1ByRef(API_PARAM(Ref) int32& a, API_PARAM(Ref) bool& b, API_PARAM(Ref) String& d, API_PARAM(Ref) StringAnsi& e, API_PARAM(Ref) Float3& f) {};
API_FUNCTION() virtual void CoverageTest1ArrayByRef(API_PARAM(Ref) Array<int32>& a, API_PARAM(Ref) Array<bool>& b, API_PARAM(Ref) Array<String>& d, API_PARAM(Ref) Array<StringAnsi>& e, API_PARAM(Ref) Array<Float3>& f) {};
API_FUNCTION() virtual void CoverageTest2(Guid a, AssetReference<FontAsset> b, Array<Guid> c, Array<AssetReference<FontAsset>> d) {};
API_FUNCTION() virtual void CoverageTest3(ModelLOD* a, API_PARAM(Out) Array<ModelLOD*>& b) {};
API_FUNCTION() virtual void CoverageTest1(int32 intParam, bool boolParam, Actor* actorParam, String& stringRefParam, StringAnsi& stringAnsiRefParam, Float3 float3Param) {};
API_FUNCTION() virtual void CoverageTest1Array(Array<int32> intArrayParam, Array<bool> boolArrayParam, Array<Actor*> actorArrayParam, Array<String> stringArrayParam, Array<StringAnsi> stringAnsiArrayParam, Array<Float3> float3ArrayParam) {};
API_FUNCTION() virtual void CoverageTest1ByRef(API_PARAM(Ref) int32& intRefParam, API_PARAM(Ref) bool& boolRefParam, API_PARAM(Ref) String& stringRefParam, API_PARAM(Ref) StringAnsi& stringAnsiRefParam, API_PARAM(Ref) Float3& float3RefParam) {};
#if false
//APIa_FUNCTION() virtual void CoverageTest1ArrayByRef(API_PARAM(Ref) Array<int32>& intArrayRefParam, API_PARAM(Ref) Array<bool>& boolArrayRefParam, API_PARAM(Ref) Array<String>& stringArrayRefParam, API_PARAM(Ref) Array<StringAnsi>& stringAnsiArrayRefParam, API_PARAM(Ref) Array<Float3>& float3ArrayRefParam) {};
#endif
API_FUNCTION() virtual void CoverageTest2(Guid guidParam, AssetReference<FontAsset> fontAssetReferenceParam, Array<Guid> guidArrayParam, Array<AssetReference<FontAsset>> fontAssetReferenceArrayParam) {};
API_FUNCTION() virtual void CoverageTest3(ModelLOD* modelLodParam, API_PARAM(Out) Array<ModelLOD*>& modelLodArrayParam) {};
#if false
//APIa_FUNCTION() virtual void CoverageTest4(BytesContainer bytesContainerParam, API_PARAM(Out) BytesContainer& bytesContainerOutParam) {};
#endif
API_FUNCTION() virtual void CoverageNamespaces1(NetworkChannelType a, Array<NetworkChannelType> b, OnlineLeaderboardSortModes c, Array<OnlineLeaderboardSortModes> d, OnlineLeaderboardValueFormats e, Array<OnlineLeaderboardValueFormats> f) {};
API_FUNCTION() virtual void SimpleCall() {};
API_FUNCTION() virtual void SimpleParams(int32 a, float b, char c, double d, int64 e) {};
API_FUNCTION() virtual void SimpleCall() { ASSERT(false); };
API_FUNCTION() virtual void SimpleParams(int32 intParam, float boolParam, char charParam, double doubleParam, int64 int64Param) {};
API_FUNCTION() virtual void StringParamAnsi(StringAnsi str) {};
API_FUNCTION() virtual void StringParam(String str) {};
API_FUNCTION() virtual void StringParamRef(String& str) {};
#if false
//API_FUNCTION() virtual void StringParamRef(String& str) {};
#endif
API_FUNCTION() virtual void StringParamRefConst(const String& str) {};
API_FUNCTION() virtual void StringParamAsRef(API_PARAM(Ref) String& str) {};
API_FUNCTION() virtual void ActorParam(Actor* actor) {};
API_FUNCTION() virtual void StringParamAsRef(API_PARAM(Ref) String& stringRefParam) {};
API_FUNCTION() virtual void ActorParam(Actor* actorParam) {};
API_FUNCTION() virtual void ComplexParam(BehaviorUpdateContext context) {};
API_FUNCTION() virtual void Complex2Param(RenderContext& context) {};
API_FUNCTION() virtual void Complex2ParamConst(const RenderContext& context) {};
API_FUNCTION() virtual void Complex2ParamAsRef(API_PARAM(Ref) RenderContext& context) {};
API_FUNCTION() virtual void SimpleArrayParam(Array<int> arr) {};
API_FUNCTION() virtual void SimpleArrayParamRef(Array<int>& arr) {};
API_FUNCTION() virtual void SimpleArrayParamRefConst(const Array<int>& arr) {};
API_FUNCTION() virtual void SimpleArrayParamAsRef(API_PARAM(Ref) Array<int>& arr) {};
API_FUNCTION() virtual void ActorArrayParam(Array<Actor*> arr) {};
API_FUNCTION() virtual void ActorArrayParamRef(Array<Actor*>& arr) {};
API_FUNCTION() virtual void ActorArrayParamRefConst(const Array<Actor*>& arr) {};
API_FUNCTION() virtual void SimpleArrayParam(Array<int> intArrayParam) {};
API_FUNCTION() virtual void SimpleArrayParamRef(Array<int>& intArrayParam) {};
API_FUNCTION() virtual void SimpleArrayParamRefConst(const Array<int>& intArrayParam) {};
API_FUNCTION() virtual void SimpleArrayParamAsRef(API_PARAM(Ref) Array<int>& intArrayRefParam) {};
API_FUNCTION() virtual void ActorArrayParam(Array<Actor*> actorArrayParam) {};
API_FUNCTION() virtual void ActorArrayParamRef(Array<Actor*>& actorArrayParam) {};
API_FUNCTION() virtual void ActorArrayParamRefConst(const Array<Actor*>& actorArrayParam) {};
//API_FUNCTION() virtual void ActorArrayParamAsRef(API_PARAM(Ref) Array<Actor*>& arr) {};
#if false
//API_FUN_CTION() virtual void ActorArrayParamAsRef(API_PARAM(Ref) Array<Actor*>& arr) {};
#endif
API_FUNCTION() virtual void ComplexArrayParam(Array<TestStruct> arr) {};
API_FUNCTION() virtual void ComplexArrayParamRef(Array<TestStruct>& arr) {};
API_FUNCTION() virtual void ComplexArrayParamRefConst(const Array<TestStruct>& arr) {};
API_FUNCTION() virtual void ComplexArrayParamAsRef(API_PARAM(Ref) Array<TestStruct>& arr) {};
API_FUNCTION() virtual void StringFieldStructParam(StringStruct& stringStruct) { ASSERT(false); };
API_FUNCTION() virtual void StringFieldStructParamAsRef(API_PARAM(Ref) StringStruct& stringStruct) { ASSERT(false); };
API_FUNCTION() virtual void StringFieldStructArrayParam(Array<StringStruct>& stringStructArray) { ASSERT(false); };
API_FUNCTION() virtual void StringFieldStructArrayParamAsRef(API_PARAM(Ref) Array<StringStruct>& stringStructArray) { ASSERT(false); };
API_FUNCTION() virtual void ComplexArrayParam(Array<TestStruct> arrayParam) {};
API_FUNCTION() virtual void ComplexArrayParamRef(Array<TestStruct>& arrayParam) {};
API_FUNCTION() virtual void ComplexArrayParamRefConst(const Array<TestStruct>& arrayParam) {};
API_FUNCTION() virtual void ComplexArrayParamAsRef(API_PARAM(Ref) Array<TestStruct>& arrayRefParam) {};
//API_EVENT() Delegate<int32, Float3, const String&, String&, TestStruct&, const Array<TestStruct>&, Array<TestStruct>&> TestEvent;
};
struct BenchmarkContext
{
MyScript2* scriptTwo;
Array<uint64> results;
};
API_CLASS() class GAME_API MyScript : public Script
{
API_AUTO_SERIALIZATION();
@@ -99,6 +129,14 @@ DECLARE_SCRIPTING_TYPE(MyScript);
//API_FIELD() MyThinger<int> thingey;
template<typename... TArgs>
void BenchmarkCall(BenchmarkContext& context, void(MyScript2::* fun)(TArgs...),
TArgs...);
//void BenchmarkCall(int times, BenchmarkContext& context, void(MyScript2::*fun)());
// [Script]
void OnStart() override;
void OnEnable() override;
@@ -109,8 +147,14 @@ DECLARE_SCRIPTING_TYPE(MyScript);
API_FUNCTION() virtual void CoverageTest1(int32 a, bool b, Actor* c, String& d, StringAnsi& e, Float3 f) {};
API_FUNCTION() virtual void CoverageTest1Array(Array<int32> a, Array<bool> b, Array<Actor*> c, Array<String> d, Array<StringAnsi> e, Array<Float3> f) {};
API_FUNCTION() virtual void CoverageTest1ByRef(API_PARAM(Ref) int32& a, API_PARAM(Ref) bool& b, API_PARAM(Ref) String& d, API_PARAM(Ref) StringAnsi& e, API_PARAM(Ref) Float3& f) {};
API_FUNCTION() virtual void CoverageTest1ArrayByRef(API_PARAM(Ref) Array<int32>& a, API_PARAM(Ref) Array<bool>& b, API_PARAM(Ref) Array<String>& d, API_PARAM(Ref) Array<StringAnsi>& e, API_PARAM(Ref) Array<Float3>& f) {};
#if false
//APIa_FUNCTION() virtual void CoverageTest1ArrayByRef(API_PARAM(Ref) Array<int32>& a, API_PARAM(Ref) Array<bool>& b, API_PARAM(Ref) Array<String>& d, API_PARAM(Ref) Array<StringAnsi>& e, API_PARAM(Ref) Array<Float3>& f) {};
#endif
API_FUNCTION() virtual void CoverageTest2(Guid a, AssetReference<FontAsset> b, Array<Guid> c, Array<AssetReference<FontAsset>> d) {};
API_FUNCTION() virtual void CoverageTest3(ModelLOD* a, API_PARAM(Out) Array<ModelLOD*>& c) {};
#if false
//APIa_FUNCTION() virtual void CoverageTest4(BytesContainer a, API_PARAM(Out) BytesContainer& b) {};
#endif
API_FUNCTION() virtual void CoverageNamespaces1(NetworkChannelType a, Array<NetworkChannelType> b, OnlineLeaderboardSortModes c, Array<OnlineLeaderboardSortModes> d, OnlineLeaderboardValueFormats e, Array<OnlineLeaderboardValueFormats> f) {};
@@ -119,7 +163,7 @@ DECLARE_SCRIPTING_TYPE(MyScript);
};
#define LOG_TEST(FUNC) \
if (thunkTests || invokeTests) LOG(Info, #FUNC);
if (thunkTests || invokeTests || callTests) LOG(Info, #FUNC);
#define BENCHMARK_INVOKE_ARGS0(REPEAT, FUNC) \
{ \
@@ -211,7 +255,7 @@ void* params[1]; \
if (params_call_orig[j+0] != params[0]) \
{ \
void* param = params_call_orig[j+0]; \
MUtils::FreeManaged<String>((MObject*)param); \
PARAM1_CLEAN((MObject*)param); \
} \
} \
} \
@@ -348,97 +392,6 @@ void* params[5]; \
LOG(Info, " - InvokeOnly: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times*chunkTimes); \
}
#define BENCHMARK_CALL_ARGS0(REPEAT, FUNC) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
results.Clear(); \
auto start2 = Platform::GetTimeCycles(); \
for (int i = 0; i < times; ++i) \
{ \
auto start = Platform::GetTimeCycles(); \
for (int j = 0; j < chunkTimes; ++j) \
scriptTwo->FUNC(); \
auto end = Platform::GetTimeCycles(); \
auto elapsed = end - start; \
results.Add(elapsed); \
} \
auto end2 = Platform::GetTimeCycles(); \
auto elapsed2 = end2 - start2; \
Sorting::MergeSort(results); \
const auto resultsIndex = 0; \
LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times*chunkTimes); \
}
#define BENCHMARK_CALL_ARGS1(REPEAT, FUNC, PARAM1) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
results.Clear(); \
auto start2 = Platform::GetTimeCycles(); \
for (int i = 0; i < times; ++i) \
{ \
auto start = Platform::GetTimeCycles(); \
for (int j = 0; j < chunkTimes; ++j) \
scriptTwo->FUNC(PARAM1); \
auto end = Platform::GetTimeCycles(); \
auto elapsed = end - start; \
results.Add(elapsed); \
} \
auto end2 = Platform::GetTimeCycles(); \
auto elapsed2 = end2 - start2; \
Sorting::MergeSort(results); \
const auto resultsIndex = 0; \
LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times*chunkTimes); \
}
#define BENCHMARK_CALL_ARGS1_REF(REPEAT, FUNC, PARAM1) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
results.Clear(); \
auto start2 = Platform::GetTimeCycles(); \
for (int i = 0; i < times; ++i) \
{ \
auto start = Platform::GetTimeCycles(); \
for (int j = 0; j < chunkTimes; ++j) \
{ \
auto _param1_orig_value = PARAM1; \
scriptTwo->FUNC(_param1_orig_value); \
} \
auto end = Platform::GetTimeCycles(); \
auto elapsed = end - start; \
results.Add(elapsed); \
} \
auto end2 = Platform::GetTimeCycles(); \
auto elapsed2 = end2 - start2; \
Sorting::MergeSort(results); \
const auto resultsIndex = 0; \
LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times*chunkTimes); \
}
#define BENCHMARK_CALL_ARGS5(REPEAT, FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
results.Clear(); \
auto start2 = Platform::GetTimeCycles(); \
for (int i = 0; i < times; ++i) \
{ \
auto start = Platform::GetTimeCycles(); \
for (int j = 0; j < chunkTimes; ++j) \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5); \
auto end = Platform::GetTimeCycles(); \
auto elapsed = end - start; \
results.Add(elapsed); \
} \
auto end2 = Platform::GetTimeCycles(); \
auto elapsed2 = end2 - start2; \
Sorting::MergeSort(results); \
const auto resultsIndex = 0; \
LOG(Info, " - VirtualCall: {:.1f}ns ({:.0f}ms total {} times)", (results[resultsIndex] * (1.0 / static_cast<double>(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast<double>(freq)) * 1000), times*chunkTimes); \
}
#define BENCHMARK_THUNK_BEGIN_ARGS0(REPEAT, FUNC) \
{ \
const auto times = REPEAT; \

View File

@@ -12,7 +12,8 @@ namespace Game;
/// </summary>
public class MyScriptTwo : MyScript2
{
private int counter = 0;
public Model Model;
/// <inheritdoc/>
public override void OnStart()
{
@@ -43,7 +44,6 @@ public class MyScriptTwo : MyScript2
public override void ManagedCoverageTests()
{
Debug.LogWarning("ManagedCoverageTests");
Actor actor = this.Actor;
MyScript script = actor.GetScript<MyScript>();
@@ -58,11 +58,30 @@ public class MyScriptTwo : MyScript2
Actor[] actors = { actor };
string[] strings = { shortString };
Float3[] float3s = { f3 };
Guid fontAssetGuid = new Guid("ab96b25a49461d9f4f819484cf5c8213");
FontAsset fontAsset = Content.LoadAsync<FontAsset>(fontAssetGuid);
ModelLOD[] modelLods = Model.LODs;
Debug.Log($"{nameof(CoverageTest1)} (Managed)");
script.CoverageTest1(1, true, actor, shortString, shortString, f3);
Debug.Log($"{nameof(CoverageTest1Array)} (Managed)");
script.CoverageTest1Array(ints, booleans, actors, strings, strings, float3s);
Debug.Log($"{nameof(CoverageTest1ByRef)} (Managed)");
script.CoverageTest1ByRef(ref ints[0], ref booleans[0]/*, ref actors[0]*/, ref strings[0], ref strings[0], ref float3s[0]);
script.CoverageTest1ArrayByRef(ref ints, ref booleans/*, ref actors*/, ref strings, ref strings, ref float3s);
//Debug.Log($"{nameof(CoverageTest1ArrayByRef)} (Managed)");
//script.CoverageTest1ArrayByRef(ref ints, ref booleans/*, ref actors*/, ref strings, ref strings, ref float3s);
Debug.Log($"{nameof(CoverageTest2)} (Managed)");
script.CoverageTest2(fontAssetGuid, fontAsset, [fontAssetGuid], [fontAsset]);
Debug.Log($"{nameof(CoverageTest3)} (Managed)");
script.CoverageTest3(modelLods[0]/*, out var modelLod*/, out var modelLodsOut);
//Debug.Log($"{nameof(CoverageTest4)} (Managed)");
//script.CoverageTest4([1], out var bytesOut);
//script.CoverageTest2(fontAssetGuid, fontAssetRef, Array<Guid>(&fontAssetGuid, 1), Array<AssetReference<FontAsset>>(&fontAssetRef, 1));
//script.CoverageNamespaces1(networkChannelType, Array<NetworkChannelType>(&networkChannelType, 1), onlineLeaderboardSortModes, Array<OnlineLeaderboardSortModes>(&onlineLeaderboardSortModes, 1), onlineLeaderboardValueFormats, Array<OnlineLeaderboardValueFormats>(&onlineLeaderboardValueFormats, 1));
}
@@ -71,16 +90,18 @@ public class MyScriptTwo : MyScript2
public override void CoverageTest1(int a, bool b, Actor c, String d, String e, Float3 f) {}
public override void CoverageTest1Array(int[] a, bool[] b, Actor[] c, String[] d, String[] e, Float3[] f) {}
public override void CoverageTest1ByRef(ref int a, ref bool b/*, ref Actor c*/, ref String d, ref String e, ref Float3 f) {}
public override void CoverageTest1ArrayByRef(ref int[] a, ref bool[] b/*, ref Actor[] c*/, ref String[] d, ref String[] e, ref Float3[] f) {}
//public override void CoverageTest1ArrayByRef(ref int[] a, ref bool[] b/*, ref Actor[] c*/, ref String[] d, ref String[] e, ref Float3[] f) {}
public override void CoverageTest2(Guid a, FontAsset b, Guid[] c, FontAsset[] d) {}
public override void CoverageTest3(ModelLOD a, out ModelLOD[] b) { b = null; }
//public override void CoverageTest4(byte[] a, out byte[] b) { b = null; }
public override void CoverageNamespaces1(NetworkChannelType a, NetworkChannelType[] b, OnlineLeaderboardSortModes c, OnlineLeaderboardSortModes[] d, OnlineLeaderboardValueFormats e, OnlineLeaderboardValueFormats[] f) {}
public override void SimpleCall() {}
public override void SimpleParams(int a, float b, sbyte c, double d, long e) {}
public override void StringParamAnsi(string str) {}
public override void StringParam(string str) {}
public override void StringParamRef(string str) {}
//public override void StringParamRef(string str) {}
public override void StringParamRefConst(string str) {}
public override void StringParamAsRef(ref string str) {}
public override void ActorParam(Actor actor) {}
@@ -96,6 +117,10 @@ public class MyScriptTwo : MyScript2
public override void ActorArrayParamRef(Actor[] arr) {}
public override void ActorArrayParamRefConst(Actor[] arr) {}
//public override void ActorArrayParamAsRef(ref Actor[] arr) {}
public override void StringFieldStructParam(StringStruct stringStruct) {}
public override void StringFieldStructParamAsRef(ref StringStruct stringStruct) {}
public override void StringFieldStructArrayParam(StringStruct[] stringStructArray) {}
public override void StringFieldStructArrayParamAsRef(ref StringStruct[] stringStructArray) { }
public override void ComplexArrayParam(TestStruct[] arr) {}
public override void ComplexArrayParamRef(TestStruct[] arr) {}
public override void ComplexArrayParamRefConst(TestStruct[] arr) {}

View File

@@ -44,6 +44,16 @@ public struct PlayerInputState2 : IEquatable<PlayerInputState2>
ViewAngles = lastInputViewAngles + ViewDelta;
ViewDelta = Float2.Zero;
}
public override bool Equals(object obj)
{
return obj is PlayerInputState2 && Equals((PlayerInputState2)obj);
}
public override int GetHashCode()
{
throw new NotImplementedException();
}
}
public interface IPlayerInput