invoke cleanup

This commit is contained in:
2025-12-22 17:26:13 +02:00
parent 3cfb7d319b
commit 8561d28642
2 changed files with 824 additions and 411 deletions

View File

@@ -19,7 +19,7 @@
#define LONGER 3
#define CHUNK_TIMES 100
#else
#define LONGER 10*10
#define LONGER 10//*10
#define CHUNK_TIMES 1000
#endif
#define TIMES (10000*LONGER)
@@ -43,230 +43,6 @@ MyScript::MyScript(const SpawnParams& params)
}
#define BENCHMARK_CALL_ARGS0(REPEAT, FUNC) \
{ \
LOG(Info, #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) \
{ \
LOG(Info, #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(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) \
{ \
LOG(Info, #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) \
{ \
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) \
{ \
LOG(Info, #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(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; \
const auto chunkTimes = CHUNK_TIMES; \
typedef void (*Thunk)(void* instance, MObject** exception); \
const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 0)->GetThunk(); \
const auto instance = scriptTwo->GetOrCreateManagedInstance(); \
MObject* exception = nullptr;
#define BENCHMARK_THUNK_CALL_ARGS0() \
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) \
thunk(instance, &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(Info, " - InvokeThunkOnly: {:.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_ARGS1(REPEAT, FUNC) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
typedef void (*Thunk)(void* instance, void*, MObject** exception); \
const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 1)->GetThunk(); \
const auto instance = scriptTwo->GetOrCreateManagedInstance(); \
MObject* exception = nullptr; \
void* params[1];
#define BENCHMARK_THUNK_CALL_ARGS1() \
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) \
thunk(instance, params[0], &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(Info, " - InvokeThunkOnly: {:.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_CALL_ARGS1_REF(FUN) \
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) \
{ \
thunk(instance, params[0], &exception); \
FUN \
} \
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, " - InvokeThunkOnly: {:.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_ARGS5(REPEAT, FUNC) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
typedef void (*Thunk)(void* instance, void*, void*, void*, void*, void*, MObject** exception); \
const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 5)->GetThunk(); \
const auto instance = scriptTwo->GetOrCreateManagedInstance(); \
MObject* exception = nullptr; \
void* params[5];
#define BENCHMARK_THUNK_CALL_ARGS5() \
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) \
thunk(instance, params[0], params[1], params[2], params[3], params[4], &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(Info, " - InvokeThunkOnly: {:.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_END() \
}
#define COVERAGE_CALL_ARGS2(FUNC, PARAM1, PARAM2) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2); \
}
#define COVERAGE_CALL_ARGS3(FUNC, PARAM1, PARAM2, PARAM3) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3); \
}
#define COVERAGE_CALL_ARGS4(FUNC, PARAM1, PARAM2, PARAM3, PARAM4) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4); \
}
#define COVERAGE_CALL_ARGS5(FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5); \
}
#define COVERAGE_CALL_ARGS6(FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6); \
}
void MyScript::OnStart()
{
LOG(Info, "C++ OnStart");
@@ -274,7 +50,10 @@ void MyScript::OnStart()
if (scriptTwo == nullptr)
return;
bool thunkTests = false;
bool invokeTests = true;
bool coverageTests = false;
bool otherTests = true;
bool arrayTests = true;
bool asRefTests = true;
@@ -337,272 +116,456 @@ void MyScript::OnStart()
if (otherTests)
{
BENCHMARK_CALL_ARGS0(TIMES2, SimpleCall);
BENCHMARK_THUNK_BEGIN_ARGS0(TIMES2, SimpleCall);
BENCHMARK_THUNK_CALL_ARGS0();
BENCHMARK_THUNK_END();
LOG_TEST(SimpleCall);
if (thunkTests)
{
BENCHMARK_CALL_ARGS0(TIMES2, SimpleCall);
BENCHMARK_THUNK_BEGIN_ARGS0(TIMES2, SimpleCall);
BENCHMARK_THUNK_CALL_ARGS0();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS0(TIMES2, SimpleCall);
}
}
if (otherTests)
{
LOG_TEST(SimpleParams);
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);
params[2] = MUtils::Box<char>('3', MCore::TypeCache::SByte);
params[3] = MUtils::Box<double>(4, MCore::TypeCache::Double);
params[4] = MUtils::Box<long>(5, MCore::TypeCache::Int64);
BENCHMARK_THUNK_CALL_ARGS5();
#if NEW_VERSION
auto __param0_handle = *(MGCHandle*)&params[0];
MCore::GCHandle::Free(__param0_handle);
auto __param1_handle = *(MGCHandle*)&params[1];
MCore::GCHandle::Free(__param1_handle);
auto __param2_handle = *(MGCHandle*)&params[2];
MCore::GCHandle::Free(__param2_handle);
auto __param3_handle = *(MGCHandle*)&params[3];
MCore::GCHandle::Free(__param3_handle);
auto __param4_handle = *(MGCHandle*)&params[4];
MCore::GCHandle::Free(__param4_handle);
#endif
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
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));
#if NEW_VERSION
auto __param0_handle = *(MGCHandle*)&params[0];
MCore::GCHandle::Free(__param0_handle);
auto __param1_handle = *(MGCHandle*)&params[1];
MCore::GCHandle::Free(__param1_handle);
auto __param2_handle = *(MGCHandle*)&params[2];
MCore::GCHandle::Free(__param2_handle);
auto __param3_handle = *(MGCHandle*)&params[3];
MCore::GCHandle::Free(__param3_handle);
auto __param4_handle = *(MGCHandle*)&params[4];
MCore::GCHandle::Free(__param4_handle);
#endif
}
}
if (otherTests)
{
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);
params[2] = MUtils::Box<char>('3', MCore::TypeCache::SByte);
params[3] = MUtils::Box<double>(4, MCore::TypeCache::Double);
params[4] = MUtils::Box<long>(5, MCore::TypeCache::Int64);
BENCHMARK_THUNK_CALL_ARGS5();
LOG_TEST(StringParamAnsi);
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();
#if NEW_VERSION
auto __param0_handle = *(MGCHandle*)&params[0];
MCore::GCHandle::Free(__param0_handle);
auto __param1_handle = *(MGCHandle*)&params[1];
MCore::GCHandle::Free(__param1_handle);
auto __param2_handle = *(MGCHandle*)&params[2];
MCore::GCHandle::Free(__param2_handle);
auto __param3_handle = *(MGCHandle*)&params[3];
MCore::GCHandle::Free(__param3_handle);
auto __param4_handle = *(MGCHandle*)&params[4];
MCore::GCHandle::Free(__param4_handle);
MUtils::FreeManaged<StringAnsi>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
}
if (otherTests)
{
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();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamAnsi,
MUtils::Box<StringAnsi>(shortStringAnsi, MCore::TypeCache::String));
#if NEW_VERSION
MUtils::FreeManaged<StringAnsi>((MObject*)params[0]);
MUtils::FreeManaged<StringAnsi>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
}
}
if (otherTests)
{
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();
LOG_TEST(StringParam);
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();
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)params[0]);
MUtils::FreeManaged<String>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParam,
MUtils::Box<String>(shortString, MCore::TypeCache::String));
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)params[0]);
#endif
}
}
if (otherTests)
{
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();
LOG_TEST(StringParamRef);
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();
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)params[0]);
MUtils::FreeManaged<String>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamRef,
MUtils::Box<String>(shortString, MCore::TypeCache::String));
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)params[0]);
#endif
}
}
if (otherTests)
{
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();
LOG_TEST(StringParamRefConst);
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();
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)params[0]);
MUtils::FreeManaged<String>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamRefConst,
MUtils::Box<String>(shortString, MCore::TypeCache::String));
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)params[0]);
#endif
}
}
if (asRefTests)
{
String str = shortString;
BENCHMARK_CALL_ARGS1_REF(TIMES3, StringParamAsRef, str);
LOG(Info, " - InvokeThunkOnly: not valid");
/* str = shortString;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, StringParamAsRef);
#if NEW_VERSION
auto __param_orig_str = MUtils::Box<String>(str, MCore::TypeCache::String);
auto __param_str = __param_orig_str;
params[0] = &__param_str;
#else
auto __param_str = MUtils::Box<String>(str, MCore::TypeCache::String);
params[0] = &__param_str;
#endif
BENCHMARK_THUNK_CALL_ARGS1_REF({ params[0] = &__param_str; });
str = MUtils::Unbox<String>(*(MObject**)params[0]);
ASSERT(str == shortString);
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)__param_str);
if (__param_orig_str != __param_str)
MUtils::FreeManaged<String>((MObject*)__param_orig_str);
#endif
BENCHMARK_THUNK_END();*/
LOG_TEST(StringParamAsRef);
if (thunkTests)
{
String str = shortString;
BENCHMARK_CALL_ARGS1_REF(TIMES3, StringParamAsRef, str);
LOG(Info, " - InvokeThunkOnly: not valid");
/* str = shortString;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, StringParamAsRef);
#if NEW_VERSION
auto __param_orig_str = MUtils::Box<String>(str, MCore::TypeCache::String);
auto __param_str = __param_orig_str;
params[0] = &__param_str;
#else
auto __param_str = MUtils::Box<String>(str, MCore::TypeCache::String);
params[0] = &__param_str;
#endif
BENCHMARK_THUNK_CALL_ARGS1_REF({ params[0] = &__param_str; });
str = MUtils::Unbox<String>(*(MObject**)params[0]);
ASSERT(str == shortString);
#if NEW_VERSION
MUtils::FreeManaged<String>((MObject*)__param_str);
if (__param_orig_str != __param_str)
MUtils::FreeManaged<String>((MObject*)__param_orig_str);
#endif
BENCHMARK_THUNK_END();*/
}
if (invokeTests)
{
String str = shortString;
BENCHMARK_INVOKE_ARGS1_REF(TIMES3, StringParamAsRef,
MUtils::Box<String>(str, MCore::TypeCache::String),
MUtils::FreeManaged<String>);
}
}
if (otherTests)
{
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();
LOG_TEST(ActorParam);
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();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, ActorParam,
ScriptingObject::ToManaged((ScriptingObject*)actor));
}
}
if (otherTests)
{
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();
LOG_TEST(ComplexParam);
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();
#if NEW_VERSION
MUtils::FreeManaged<BehaviorUpdateContext>((MObject*)params[0]);
MUtils::FreeManaged<BehaviorUpdateContext>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES2, ComplexParam,
MUtils::Box<BehaviorUpdateContext>(behaviorUpdateContext, BehaviorUpdateContext::TypeInitializer.GetClass()));
#if NEW_VERSION
MUtils::FreeManaged<BehaviorUpdateContext>((MObject*)params[0]);
#endif
}
}
if (otherTests)
{
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();
LOG_TEST(Complex2Param);
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();
#if NEW_VERSION
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2Param,
MUtils::Box<RenderContext>(renderContext, RenderContext::TypeInitializer.GetClass()));
#if NEW_VERSION
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
#endif
}
}
if (otherTests)
{
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();
LOG_TEST(Complex2ParamConst);
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();
#if NEW_VERSION
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2ParamConst,
MUtils::Box<RenderContext>(renderContext, RenderContext::TypeInitializer.GetClass()));
#if NEW_VERSION
MUtils::FreeManaged<RenderContext>((MObject*)params[0]);
#endif
}
}
if (asRefTests)
{
RenderContext context = renderContext;
BENCHMARK_CALL_ARGS1_REF(TIMES4, Complex2ParamAsRef, context);
LOG(Info, " - InvokeThunkOnly: not valid");
/* context = renderContext;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2ParamAsRef);
#if NEW_VERSION
auto __param_orig_context = MUtils::Box<RenderContext>(context, RenderContext::TypeInitializer.GetClass());
auto __param_context = __param_orig_context;
params[0] = &__param_context;
#else
auto __param_context = MUtils::Box<RenderContext>(context, RenderContext::TypeInitializer.GetClass());
params[0] = &__param_context;
#endif
BENCHMARK_THUNK_CALL_ARGS1_REF({ if (__param_orig_context != __param_context) MUtils::FreeManaged<RenderContext>((MObject*)__param_orig_context); params[0] = &__param_context; });
context = MUtils::Unbox<RenderContext>(*(MObject**)params[0]);
ASSERT(context.Buffers == renderContext.Buffers);
ASSERT(context.Task == renderContext.Task);
#if NEW_VERSION
context = MUtils::Unbox<RenderContext>(*(MObject**)params[0]);
MUtils::FreeManaged<RenderContext>((MObject*)__param_context);
if (__param_orig_context != __param_context)
MUtils::FreeManaged<RenderContext>((MObject*)__param_orig_context);
#endif
BENCHMARK_THUNK_END();*/
LOG_TEST(Complex2ParamAsRef);
if (thunkTests)
{
RenderContext context = renderContext;
BENCHMARK_CALL_ARGS1_REF(TIMES4, Complex2ParamAsRef, context);
LOG(Info, " - InvokeThunkOnly: not valid");
/* context = renderContext;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2ParamAsRef);
#if NEW_VERSION
auto __param_orig_context = MUtils::Box<RenderContext>(context, RenderContext::TypeInitializer.GetClass());
auto __param_context = __param_orig_context;
params[0] = &__param_context;
#else
auto __param_context = MUtils::Box<RenderContext>(context, RenderContext::TypeInitializer.GetClass());
params[0] = &__param_context;
#endif
BENCHMARK_THUNK_CALL_ARGS1_REF({ if (__param_orig_context != __param_context) MUtils::FreeManaged<RenderContext>((MObject*)__param_orig_context); params[0] = &__param_context; });
context = MUtils::Unbox<RenderContext>(*(MObject**)params[0]);
ASSERT(context.Buffers == renderContext.Buffers);
ASSERT(context.Task == renderContext.Task);
#if NEW_VERSION
context = MUtils::Unbox<RenderContext>(*(MObject**)params[0]);
MUtils::FreeManaged<RenderContext>((MObject*)__param_context);
if (__param_orig_context != __param_context)
MUtils::FreeManaged<RenderContext>((MObject*)__param_orig_context);
#endif
BENCHMARK_THUNK_END();*/
}
}
if (arrayTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, SimpleArrayParam, simpleArray);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, SimpleArrayParam);
params[0] = MUtils::ToArray(simpleArray, MCore::TypeCache::Int32);
BENCHMARK_THUNK_CALL_ARGS1();
LOG_TEST(SimpleArrayParam);
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();
#if NEW_VERSION
MUtils::FreeManagedArray<int>((MArray*)params[0]);
MUtils::FreeManagedArray<int>((MArray*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, SimpleArrayParam,
MUtils::ToArray(simpleArray, MCore::TypeCache::Int32));
#if NEW_VERSION
MUtils::FreeManagedArray<int>((MArray*)params[0]);
#endif
}
}
if (arrayTests && asRefTests)
{
Array<int> arr = simpleArray;
BENCHMARK_CALL_ARGS1_REF(TIMES4, SimpleArrayParamAsRef, simpleArray);
LOG(Info, " - InvokeThunkOnly: not valid");
/* arr = simpleArray;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, SimpleArrayParamAsRef);
#if NEW_VERSION
auto __param_orig_arr = MUtils::ToArray(arr, MCore::TypeCache::Int32);
auto __param_arr = __param_orig_arr;
params[0] = &__param_arr;
#else
auto __param_arr = MUtils::ToArray(arr, MCore::TypeCache::Int32);
params[0] = &__param_arr;
#endif
BENCHMARK_THUNK_CALL_ARGS1();
arr = MUtils::Unbox<Array<int>>(*(MObject**)params[0]);
ASSERT(arr.Count() == simpleArray.Count());
for (int i=0; i<arr.Count(); i++) ASSERT(arr[i] == simpleArray[i]);
#if NEW_VERSION
MUtils::FreeManagedArray<int>(__param_arr); //fgfgh3
if (__param_orig_arr != __param_arr)
MUtils::FreeManagedArray<int>(__param_orig_arr); //fgfgh4
#endif
BENCHMARK_THUNK_END();*/
LOG_TEST(SimpleArrayParamAsRef);
if (thunkTests)
{
Array<int> arr = simpleArray;
BENCHMARK_CALL_ARGS1_REF(TIMES4, SimpleArrayParamAsRef, simpleArray);
LOG(Info, " - InvokeThunkOnly: not valid");
/* arr = simpleArray;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, SimpleArrayParamAsRef);
#if NEW_VERSION
auto __param_orig_arr = MUtils::ToArray(arr, MCore::TypeCache::Int32);
auto __param_arr = __param_orig_arr;
params[0] = &__param_arr;
#else
auto __param_arr = MUtils::ToArray(arr, MCore::TypeCache::Int32);
params[0] = &__param_arr;
#endif
BENCHMARK_THUNK_CALL_ARGS1();
arr = MUtils::Unbox<Array<int>>(*(MObject**)params[0]);
ASSERT(arr.Count() == simpleArray.Count());
for (int i=0; i<arr.Count(); i++) ASSERT(arr[i] == simpleArray[i]);
#if NEW_VERSION
MUtils::FreeManagedArray<int>(__param_arr); //fgfgh3
if (__param_orig_arr != __param_arr)
MUtils::FreeManagedArray<int>(__param_orig_arr); //fgfgh4
#endif
BENCHMARK_THUNK_END();*/
}
}
if (arrayTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, ActorArrayParam, actorArray);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, ActorArrayParam);
params[0] = MUtils::ToArray(actorArray, Actor::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
LOG_TEST(ActorArrayParam);
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();
#if NEW_VERSION
MUtils::FreeManagedArray<Actor*>((MArray*)params[0]);
MUtils::FreeManagedArray<Actor*>((MArray*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, ActorArrayParam,
MUtils::ToArray(actorArray, Actor::TypeInitializer.GetClass()));
#if NEW_VERSION
MUtils::FreeManagedArray<Actor*>((MArray*)params[0]);
#endif
}
}
if (arrayTests)
{
BENCHMARK_CALL_ARGS1(TIMES4, ComplexArrayParam, complexArray);
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, ComplexArrayParam);
params[0] = MUtils::ToArray(complexArray, TestStruct::TypeInitializer.GetClass());
BENCHMARK_THUNK_CALL_ARGS1();
LOG_TEST(ComplexArrayParam);
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();
#if NEW_VERSION
MUtils::FreeManagedArray<TestStruct>((MArray*)params[0]);
MUtils::FreeManagedArray<TestStruct>((MArray*)params[0]);
#endif
BENCHMARK_THUNK_END();
BENCHMARK_THUNK_END();
}
if (invokeTests)
{
BENCHMARK_INVOKE_ARGS1(TIMES3, ComplexArrayParam,
MUtils::ToArray(complexArray, TestStruct::TypeInitializer.GetClass()));
#if NEW_VERSION
MUtils::FreeManagedArray<TestStruct>((MArray*)params[0]);
#endif
}
}
if (arrayTests && asRefTests)
{
Array<TestStruct> arr = complexArray;
BENCHMARK_CALL_ARGS1_REF(TIMES4, ComplexArrayParamAsRef, arr);
LOG(Info, " - InvokeThunkOnly: not valid");
/* arr = complexArray;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES4, ComplexArrayParamAsRef);
#if NEW_VERSION
auto __param_orig_arr = MUtils::ToArray(arr, TestStruct::TypeInitializer.GetClass());
auto __param_arr = __param_orig_arr;
params[0] = &__param_arr;
#else
auto __param_arr = MUtils::ToArray(arr, TestStruct::TypeInitializer.GetClass());
params[0] = &__param_arr;
#endif
BENCHMARK_THUNK_CALL_ARGS1();
arr = MUtils::Unbox<Array<TestStruct>>(*(MObject**)params[0]);
ASSERT(arr.Count() == complexArray.Count());
for (int i = 0; i < arr.Count(); i++) ASSERT(arr[i] == complexArray[i]);
#if NEW_VERSION
MUtils::FreeManagedArray<TestStruct>(__param_arr);
if (__param_orig_arr != __param_arr)
MUtils::FreeManagedArray<TestStruct>(__param_orig_arr);
#endif
BENCHMARK_THUNK_END();*/
LOG_TEST(ComplexArrayParamAsRef);
if (thunkTests)
{
Array<TestStruct> arr = complexArray;
BENCHMARK_CALL_ARGS1_REF(TIMES4, ComplexArrayParamAsRef, arr);
LOG(Info, " - InvokeThunkOnly: not valid");
/* arr = complexArray;
BENCHMARK_THUNK_BEGIN_ARGS1(TIMES4, ComplexArrayParamAsRef);
#if NEW_VERSION
auto __param_orig_arr = MUtils::ToArray(arr, TestStruct::TypeInitializer.GetClass());
auto __param_arr = __param_orig_arr;
params[0] = &__param_arr;
#else
auto __param_arr = MUtils::ToArray(arr, TestStruct::TypeInitializer.GetClass());
params[0] = &__param_arr;
#endif
BENCHMARK_THUNK_CALL_ARGS1();
arr = MUtils::Unbox<Array<TestStruct>>(*(MObject**)params[0]);
ASSERT(arr.Count() == complexArray.Count());
for (int i = 0; i < arr.Count(); i++) ASSERT(arr[i] == complexArray[i]);
#if NEW_VERSION
MUtils::FreeManagedArray<TestStruct>(__param_arr);
if (__param_orig_arr != __param_arr)
MUtils::FreeManagedArray<TestStruct>(__param_orig_arr);
#endif
BENCHMARK_THUNK_END();*/
}
}
#if NEW_VERSION

View File

@@ -117,3 +117,453 @@ DECLARE_SCRIPTING_TYPE(MyScript);
//API_FUNCTION() void Test1(API_PARAM(REF) Array<TestTypeEnum>& eenums) {};
//API_FUNCTION() BezierCurve<Transform>.Keyframe Test2(BezierCurve<Transform> kef) {};
};
#define LOG_TEST(FUNC) \
if (thunkTests || invokeTests) LOG(Info, #FUNC);
#define BENCHMARK_INVOKE_ARGS0(REPEAT, FUNC) \
{ \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, 0); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
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) \
method->Invoke(instance, nullptr, &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(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_INVOKE_ARGS1(REPEAT, FUNC, PARAM1) \
void* params[1]; \
{ \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, 1); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
params[0] = PARAM1; \
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(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_INVOKE_ARGS1_REF(REPEAT, FUNC, PARAM1, PARAM1_CLEAN) \
{ \
auto const NUM_PARAMS = 1; \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, NUM_PARAMS); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
void* params[NUM_PARAMS]; \
params[0] = PARAM1; \
results.Clear(); \
auto start2 = Platform::GetTimeCycles(); \
for (int i = 0; i < times; ++i) \
{ \
void* params_call[CHUNK_TIMES * NUM_PARAMS]; \
void* params_call_orig[CHUNK_TIMES * NUM_PARAMS]; \
for (int j = 0; j < chunkTimes * NUM_PARAMS; j += NUM_PARAMS) \
{ \
params_call_orig[j+0] = params[0]; \
params_call[j+0] = &params_call_orig[j+0]; \
} \
auto start = Platform::GetTimeCycles(); \
for (int j = 0; j < chunkTimes; ++j) \
{ \
method->Invoke(instance, &params_call[j * NUM_PARAMS], &exception); \
} \
auto end = Platform::GetTimeCycles(); \
auto elapsed = end - start; \
results.Add(elapsed); \
for (int j = 0; j < chunkTimes * NUM_PARAMS; j += NUM_PARAMS) \
{ \
if (params_call_orig[j+0] != params[0]) \
{ \
void* param = params_call_orig[j+0]; \
MUtils::FreeManaged<String>((MObject*)param); \
} \
} \
} \
auto end2 = Platform::GetTimeCycles(); \
auto elapsed2 = end2 - start2; \
Sorting::MergeSort(results); \
{ \
void* param = params[0]; \
PARAM1_CLEAN((MObject*)param); \
} \
const auto resultsIndex = 0; \
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_INVOKE_ARGS2(REPEAT, FUNC, PARAM1, PARAM2) \
void* params[2]; \
{ \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, 2); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
params[0] = PARAM1; \
params[1] = PARAM2; \
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(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_INVOKE_ARGS3(REPEAT, FUNC, PARAM1, PARAM2, PARAM3) \
void* params[3]; \
{ \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, 3); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
params[0] = PARAM1; \
params[1] = PARAM2; \
params[2] = PARAM3; \
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(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_INVOKE_ARGS4(REPEAT, FUNC, PARAM1, PARAM2, PARAM3, PARAM4) \
void* params[4]; \
{ \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, 4); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
params[0] = PARAM1; \
params[1] = PARAM2; \
params[2] = PARAM3; \
params[3] = PARAM4; \
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(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_INVOKE_ARGS5(REPEAT, FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \
void* params[5]; \
{ \
auto klass = MyScript2::GetStaticClass(); \
auto method = klass->GetMethod(#FUNC, 5); \
auto instance = scriptTwo->GetManagedInstance(); \
MObject* exception = nullptr; \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
const auto freq = Platform::GetClockFrequency(); \
params[0] = PARAM1; \
params[1] = PARAM2; \
params[2] = PARAM3; \
params[3] = PARAM4; \
params[4] = PARAM5; \
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(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; \
const auto chunkTimes = CHUNK_TIMES; \
typedef void (*Thunk)(void* instance, MObject** exception); \
const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 0)->GetThunk(); \
const auto instance = scriptTwo->GetOrCreateManagedInstance(); \
MObject* exception = nullptr;
#define BENCHMARK_THUNK_CALL_ARGS0() \
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) \
thunk(instance, &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(Info, " - InvokeThunkOnly: {:.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_ARGS1(REPEAT, FUNC) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
typedef void (*Thunk)(void* instance, void*, MObject** exception); \
const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 1)->GetThunk(); \
const auto instance = scriptTwo->GetOrCreateManagedInstance(); \
MObject* exception = nullptr; \
void* params[1];
#define BENCHMARK_THUNK_CALL_ARGS1() \
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) \
thunk(instance, params[0], &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(Info, " - InvokeThunkOnly: {:.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_CALL_ARGS1_REF(FUN) \
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) \
{ \
thunk(instance, params[0], &exception); \
FUN \
} \
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, " - InvokeThunkOnly: {:.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_ARGS5(REPEAT, FUNC) \
{ \
const auto times = REPEAT; \
const auto chunkTimes = CHUNK_TIMES; \
typedef void (*Thunk)(void* instance, void*, void*, void*, void*, void*, MObject** exception); \
const auto thunk = (Thunk)scriptTwo->GetClass()->GetMethod(#FUNC, 5)->GetThunk(); \
const auto instance = scriptTwo->GetOrCreateManagedInstance(); \
MObject* exception = nullptr; \
void* params[5];
#define BENCHMARK_THUNK_CALL_ARGS5() \
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) \
thunk(instance, params[0], params[1], params[2], params[3], params[4], &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(Info, " - InvokeThunkOnly: {:.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_END() \
}
#define COVERAGE_CALL_ARGS2(FUNC, PARAM1, PARAM2) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2); \
}
#define COVERAGE_CALL_ARGS3(FUNC, PARAM1, PARAM2, PARAM3) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3); \
}
#define COVERAGE_CALL_ARGS4(FUNC, PARAM1, PARAM2, PARAM3, PARAM4) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4); \
}
#define COVERAGE_CALL_ARGS5(FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5); \
}
#define COVERAGE_CALL_ARGS6(FUNC, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6) \
{ \
LOG(Info, #FUNC); \
scriptTwo->FUNC(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6); \
}