diff --git a/Source/Game/MyScript.cpp b/Source/Game/MyScript.cpp index 65cea9d..4076e44 100644 --- a/Source/Game/MyScript.cpp +++ b/Source/Game/MyScript.cpp @@ -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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(1, MCore::TypeCache::Int32); + params[1] = MUtils::Box(2, MCore::TypeCache::Single); + params[2] = MUtils::Box('3', MCore::TypeCache::SByte); + params[3] = MUtils::Box(4, MCore::TypeCache::Double); + params[4] = MUtils::Box(5, MCore::TypeCache::Int64); + BENCHMARK_THUNK_CALL_ARGS5(); +#if NEW_VERSION + auto __param0_handle = *(MGCHandle*)¶ms[0]; + MCore::GCHandle::Free(__param0_handle); + auto __param1_handle = *(MGCHandle*)¶ms[1]; + MCore::GCHandle::Free(__param1_handle); + auto __param2_handle = *(MGCHandle*)¶ms[2]; + MCore::GCHandle::Free(__param2_handle); + auto __param3_handle = *(MGCHandle*)¶ms[3]; + MCore::GCHandle::Free(__param3_handle); + auto __param4_handle = *(MGCHandle*)¶ms[4]; + MCore::GCHandle::Free(__param4_handle); +#endif + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS5(TIMES3, SimpleParams, + MUtils::Box(1, MCore::TypeCache::Int32), + MUtils::Box(2, MCore::TypeCache::Single), + MUtils::Box('3', MCore::TypeCache::SByte), + MUtils::Box(4, MCore::TypeCache::Double), + MUtils::Box(5, MCore::TypeCache::Int64)); +#if NEW_VERSION + auto __param0_handle = *(MGCHandle*)¶ms[0]; + MCore::GCHandle::Free(__param0_handle); + auto __param1_handle = *(MGCHandle*)¶ms[1]; + MCore::GCHandle::Free(__param1_handle); + auto __param2_handle = *(MGCHandle*)¶ms[2]; + MCore::GCHandle::Free(__param2_handle); + auto __param3_handle = *(MGCHandle*)¶ms[3]; + MCore::GCHandle::Free(__param3_handle); + auto __param4_handle = *(MGCHandle*)¶ms[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(1, MCore::TypeCache::Int32); - params[1] = MUtils::Box(2, MCore::TypeCache::Single); - params[2] = MUtils::Box('3', MCore::TypeCache::SByte); - params[3] = MUtils::Box(4, MCore::TypeCache::Double); - params[4] = MUtils::Box(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(shortStringAnsi, MCore::TypeCache::String); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - auto __param0_handle = *(MGCHandle*)¶ms[0]; - MCore::GCHandle::Free(__param0_handle); - auto __param1_handle = *(MGCHandle*)¶ms[1]; - MCore::GCHandle::Free(__param1_handle); - auto __param2_handle = *(MGCHandle*)¶ms[2]; - MCore::GCHandle::Free(__param2_handle); - auto __param3_handle = *(MGCHandle*)¶ms[3]; - MCore::GCHandle::Free(__param3_handle); - auto __param4_handle = *(MGCHandle*)¶ms[4]; - MCore::GCHandle::Free(__param4_handle); + MUtils::FreeManaged((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(shortStringAnsi, MCore::TypeCache::String); - BENCHMARK_THUNK_CALL_ARGS1(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamAnsi, + MUtils::Box(shortStringAnsi, MCore::TypeCache::String)); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((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(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(shortString, MCore::TypeCache::String); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((MObject*)params[0]); #endif - BENCHMARK_THUNK_END(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES2, StringParam, + MUtils::Box(shortString, MCore::TypeCache::String)); +#if NEW_VERSION + MUtils::FreeManaged((MObject*)params[0]); +#endif + } } if (otherTests) { - BENCHMARK_CALL_ARGS1(TIMES3, StringParamRef, shortString); - BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, StringParamRef); - params[0] = MUtils::Box(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(shortString, MCore::TypeCache::String); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((MObject*)params[0]); #endif - BENCHMARK_THUNK_END(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamRef, + MUtils::Box(shortString, MCore::TypeCache::String)); +#if NEW_VERSION + MUtils::FreeManaged((MObject*)params[0]); +#endif + } } if (otherTests) { - BENCHMARK_CALL_ARGS1(TIMES3, StringParamRefConst, shortString); - BENCHMARK_THUNK_BEGIN_ARGS1(TIMES2, StringParamRefConst); - params[0] = MUtils::Box(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(shortString, MCore::TypeCache::String); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((MObject*)params[0]); #endif - BENCHMARK_THUNK_END(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES2, StringParamRefConst, + MUtils::Box(shortString, MCore::TypeCache::String)); +#if NEW_VERSION + MUtils::FreeManaged((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(str, MCore::TypeCache::String); - auto __param_str = __param_orig_str; - params[0] = &__param_str; -#else - auto __param_str = MUtils::Box(str, MCore::TypeCache::String); - params[0] = &__param_str; -#endif - BENCHMARK_THUNK_CALL_ARGS1_REF({ params[0] = &__param_str; }); - str = MUtils::Unbox(*(MObject**)params[0]); - ASSERT(str == shortString); -#if NEW_VERSION - MUtils::FreeManaged((MObject*)__param_str); - if (__param_orig_str != __param_str) - MUtils::FreeManaged((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(str, MCore::TypeCache::String); + auto __param_str = __param_orig_str; + params[0] = &__param_str; + #else + auto __param_str = MUtils::Box(str, MCore::TypeCache::String); + params[0] = &__param_str; + #endif + BENCHMARK_THUNK_CALL_ARGS1_REF({ params[0] = &__param_str; }); + str = MUtils::Unbox(*(MObject**)params[0]); + ASSERT(str == shortString); + #if NEW_VERSION + MUtils::FreeManaged((MObject*)__param_str); + if (__param_orig_str != __param_str) + MUtils::FreeManaged((MObject*)__param_orig_str); + #endif + BENCHMARK_THUNK_END();*/ + } + if (invokeTests) + { + String str = shortString; + BENCHMARK_INVOKE_ARGS1_REF(TIMES3, StringParamAsRef, + MUtils::Box(str, MCore::TypeCache::String), + MUtils::FreeManaged); + } } 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::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::TypeInitializer.GetClass()); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((MObject*)params[0]); #endif - BENCHMARK_THUNK_END(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES2, ComplexParam, + MUtils::Box(behaviorUpdateContext, BehaviorUpdateContext::TypeInitializer.GetClass())); +#if NEW_VERSION + MUtils::FreeManaged((MObject*)params[0]); +#endif + } } if (otherTests) { - BENCHMARK_CALL_ARGS1(TIMES4, Complex2Param, renderContext); - BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2Param); - params[0] = MUtils::Box(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::TypeInitializer.GetClass()); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((MObject*)params[0]); #endif - BENCHMARK_THUNK_END(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2Param, + MUtils::Box(renderContext, RenderContext::TypeInitializer.GetClass())); +#if NEW_VERSION + MUtils::FreeManaged((MObject*)params[0]); +#endif + } } if (otherTests) { - BENCHMARK_CALL_ARGS1(TIMES4, Complex2ParamConst, renderContext); - BENCHMARK_THUNK_BEGIN_ARGS1(TIMES3, Complex2ParamConst); - params[0] = MUtils::Box(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::TypeInitializer.GetClass()); + BENCHMARK_THUNK_CALL_ARGS1(); #if NEW_VERSION - MUtils::FreeManaged((MObject*)params[0]); + MUtils::FreeManaged((MObject*)params[0]); #endif - BENCHMARK_THUNK_END(); + BENCHMARK_THUNK_END(); + } + if (invokeTests) + { + BENCHMARK_INVOKE_ARGS1(TIMES3, Complex2ParamConst, + MUtils::Box(renderContext, RenderContext::TypeInitializer.GetClass())); +#if NEW_VERSION + MUtils::FreeManaged((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(context, RenderContext::TypeInitializer.GetClass()); - auto __param_context = __param_orig_context; - params[0] = &__param_context; -#else - auto __param_context = MUtils::Box(context, RenderContext::TypeInitializer.GetClass()); - params[0] = &__param_context; -#endif - BENCHMARK_THUNK_CALL_ARGS1_REF({ if (__param_orig_context != __param_context) MUtils::FreeManaged((MObject*)__param_orig_context); params[0] = &__param_context; }); - context = MUtils::Unbox(*(MObject**)params[0]); - ASSERT(context.Buffers == renderContext.Buffers); - ASSERT(context.Task == renderContext.Task); -#if NEW_VERSION - context = MUtils::Unbox(*(MObject**)params[0]); - MUtils::FreeManaged((MObject*)__param_context); - if (__param_orig_context != __param_context) - MUtils::FreeManaged((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(context, RenderContext::TypeInitializer.GetClass()); + auto __param_context = __param_orig_context; + params[0] = &__param_context; + #else + auto __param_context = MUtils::Box(context, RenderContext::TypeInitializer.GetClass()); + params[0] = &__param_context; + #endif + BENCHMARK_THUNK_CALL_ARGS1_REF({ if (__param_orig_context != __param_context) MUtils::FreeManaged((MObject*)__param_orig_context); params[0] = &__param_context; }); + context = MUtils::Unbox(*(MObject**)params[0]); + ASSERT(context.Buffers == renderContext.Buffers); + ASSERT(context.Task == renderContext.Task); + #if NEW_VERSION + context = MUtils::Unbox(*(MObject**)params[0]); + MUtils::FreeManaged((MObject*)__param_context); + if (__param_orig_context != __param_context) + MUtils::FreeManaged((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((MArray*)params[0]); + MUtils::FreeManagedArray((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((MArray*)params[0]); +#endif + } } if (arrayTests && asRefTests) { - Array 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>(*(MObject**)params[0]); - ASSERT(arr.Count() == simpleArray.Count()); - for (int i=0; i(__param_arr); //fgfgh3 - if (__param_orig_arr != __param_arr) - MUtils::FreeManagedArray(__param_orig_arr); //fgfgh4 -#endif - BENCHMARK_THUNK_END();*/ + LOG_TEST(SimpleArrayParamAsRef); + if (thunkTests) + { + Array 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>(*(MObject**)params[0]); + ASSERT(arr.Count() == simpleArray.Count()); + for (int i=0; i(__param_arr); //fgfgh3 + if (__param_orig_arr != __param_arr) + MUtils::FreeManagedArray(__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((MArray*)params[0]); + MUtils::FreeManagedArray((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((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((MArray*)params[0]); + MUtils::FreeManagedArray((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((MArray*)params[0]); +#endif + } } if (arrayTests && asRefTests) { - Array 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>(*(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(__param_arr); - if (__param_orig_arr != __param_arr) - MUtils::FreeManagedArray(__param_orig_arr); -#endif - BENCHMARK_THUNK_END();*/ + LOG_TEST(ComplexArrayParamAsRef); + if (thunkTests) + { + Array 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>(*(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(__param_arr); + if (__param_orig_arr != __param_arr) + MUtils::FreeManagedArray(__param_orig_arr); + #endif + BENCHMARK_THUNK_END();*/ + } } #if NEW_VERSION diff --git a/Source/Game/MyScript.h b/Source/Game/MyScript.h index f776963..6c2bf31 100644 --- a/Source/Game/MyScript.h +++ b/Source/Game/MyScript.h @@ -117,3 +117,453 @@ DECLARE_SCRIPTING_TYPE(MyScript); //API_FUNCTION() void Test1(API_PARAM(REF) Array& eenums) {}; //API_FUNCTION() BezierCurve.Keyframe Test2(BezierCurve 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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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] = ¶ms_call_orig[j+0]; \ + } \ + auto start = Platform::GetTimeCycles(); \ + for (int j = 0; j < chunkTimes; ++j) \ + { \ + method->Invoke(instance, ¶ms_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((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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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(freq)) * 1000000000 / chunkTimes), (elapsed2 * (1.0 / static_cast(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); \ +}