diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-07-10 10:55:13 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-09-04 11:06:23 +0200 |
| commit | c212b34cc12c69fd380e0b1a2ed3bbf41826345d (patch) | |
| tree | d6aa97767eea2049ca195934e539dc6594e26cbc | |
| parent | 78092ce771c506873b2839b70ad7c488a01535c3 (diff) | |
add time measure in samples
| -rw-r--r-- | samples/SampleApp.cpp | 33 | ||||
| -rw-r--r-- | samples/SampleApp.hpp | 16 | ||||
| -rw-r--r-- | samples/VkvgTest.cpp | 54 | ||||
| -rw-r--r-- | samples/VkvgTest.hpp | 12 | ||||
| -rw-r--r-- | samples/tests/clip.cpp | 24 |
5 files changed, 124 insertions, 15 deletions
diff --git a/samples/SampleApp.cpp b/samples/SampleApp.cpp index 3ac7e64..16bf11b 100644 --- a/samples/SampleApp.cpp +++ b/samples/SampleApp.cpp @@ -1,5 +1,6 @@ #include <iostream> #include <stdio.h> +#include <chrono> #include "vkvg.h" #include "vkh.h" @@ -183,6 +184,9 @@ void SampleApp::Run() { int testIdx = 0; auto it = VkvgTest::tests.begin(); VkvgTest* curTest = NULL; + std::vector<double> run_time_values; + run_time_values.reserve(iterations); + double totTime = 0; if (testsToRun.empty()) { curTest = (*it); @@ -191,24 +195,41 @@ void SampleApp::Run() { } glfwSetWindowTitle(win, curTest->name.c_str()); + curTest->initTest(this); + curTest->performTest(testIdx);//warm-up while (!glfwWindowShouldClose(win)) { glfwPollEvents(); - curTest->performTest(); + int idx = testIdx; + auto start = std::chrono::steady_clock::now(); + DoNotOptimize(idx); + int res = curTest->performTest(idx); + DoNotOptimize(res); + auto finish = std::chrono::steady_clock::now(); + + auto elapsed = finish - start; + /*double elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>( + elapsed).count();*/ + double elapsed_ms = std::chrono::duration<double, std::milli>(elapsed).count(); + if (!vkh_presenter_draw(renderer)) { vkh_presenter_get_size(renderer, &width, &height); - curTest->cleanTest(); + curTest->cleanTest(0, nullptr); curTest->initTest(this); + curTest->performTest(testIdx);//warm-up continue; } if (iterations > 0) { + totTime += elapsed_ms; + run_time_values.push_back(elapsed_ms); + if (++curIter == iterations) { + curTest->cleanTest(totTime, run_time_values.data()); testIdx++; - curTest->cleanTest(); if (testsToRun.empty()) { if (++it == VkvgTest::tests.end()) { curTest = NULL; @@ -224,13 +245,17 @@ void SampleApp::Run() { } curIter = 0; + totTime = 0; + run_time_values.clear(); + run_time_values.reserve(iterations); glfwSetWindowTitle(win, curTest->name.c_str()); curTest->initTest(this); + curTest->performTest(testIdx);//warm-up } } } if (curTest != NULL) - curTest->cleanTest(); + curTest->cleanTest(totTime, run_time_values.data()); } void SampleApp::CleanUp() { diff --git a/samples/SampleApp.hpp b/samples/SampleApp.hpp index e999a25..959d2be 100644 --- a/samples/SampleApp.hpp +++ b/samples/SampleApp.hpp @@ -12,6 +12,22 @@ if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL)) \ enabledExts[enabledExtsCount++] = #ext; \ } +#if defined(__GNUC__) || defined(__clang__) +#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline)) +#elif defined(_MSC_VER) && !defined(__clang__) +#define BENCHMARK_ALWAYS_INLINE __forceinline +#define __func__ __FUNCTION__ +#else +#define BENCHMARK_ALWAYS_INLINE +#endif +template <class Tp> +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { +#if defined(__clang__) + asm volatile("" : "+r,m"(value) : : "memory"); +#else + asm volatile("" : "+m,r"(value) : : "memory"); +#endif +} class SampleApp { bool try_get_phyinfo(VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy); diff --git a/samples/VkvgTest.cpp b/samples/VkvgTest.cpp index 02933b0..6f5be46 100644 --- a/samples/VkvgTest.cpp +++ b/samples/VkvgTest.cpp @@ -1,10 +1,35 @@ +#include <iostream> #include "VkvgTest.hpp" +double median_run_time(double data[], int n) { + double temp; + int i, j; + for (i = 0; i < n; i++) + for (j = i + 1; j < n; j++) { + if (data[i] > data[j]) { + temp = data[j]; + data[j] = data[i]; + data[i] = temp; + } + } + if (n % 2 == 0) + return ((data[n / 2] + data[n / 2 - 1]) / 2); + return data[n / 2]; +} +double standard_deviation(const double data[], int n, double mean) { + double sum_deviation = 0.0; + int i; + for (i = 0; i < n; ++i) + sum_deviation += (data[i] - mean) * (data[i] - mean); + return sqrt(sum_deviation / n); +} + std::vector<VkvgTest*> VkvgTest::tests; VkvgTest::VkvgTest(VkvgTestFunc testFunc, std::string _name) { this->testFunc = testFunc; this->name = _name; + this->index = VkvgTest::tests.size(); VkvgTest::tests.push_back(this); } void VkvgTest::initTest(SampleApp* app) { @@ -27,8 +52,11 @@ void VkvgTest::initTest(SampleApp* app) { vkDeviceWaitIdle(vkh_device_get_vkdev(app->vkhDev)); } -void VkvgTest::performTest() { testFunc(this); } -void VkvgTest::cleanTest() { +int VkvgTest::performTest(int inst) { + testFunc(this); + return inst; +} +void VkvgTest::cleanTest(double _totTime, double* run_time_values) { vkDeviceWaitIdle(vkh_device_get_vkdev(app->vkhDev)); if (this->app->save_img) { std::string path = this->name + ".png"; @@ -36,9 +64,29 @@ void VkvgTest::cleanTest() { } vkvg_surface_destroy(surf); vkvg_device_destroy(device); + if (run_time_values) { + double count = app->iterations; + this->totTime = _totTime; + avg_run_time = totTime / count; + med_run_time = median_run_time(run_time_values, count); + standard_dev = standard_deviation(run_time_values, count, avg_run_time); + avg_frames_per_second = (1.0 / avg_run_time); + std::cout.imbue(std::locale("en_US.utf8")); + std::cout << "\uFF5C "<< std::right << std::setw(3) << std::setprecision(3) << this->index << " \uFF5C "; + std::cout << std::left << std::setw(40) << this->name << "\uFF5C"; + //std::cout << std::right << std::setw(10) << std::setprecision(3) << std::fixed << this->totTime * 1000 << " \uFF5C "; + std::cout << std::right << std::setw(10) << std::setprecision(5) << std::fixed << this->avg_run_time << " \uFF5C "; + std::cout << std::right << std::setw(10) << std::setprecision(5) << std::fixed << this->med_run_time << " \uFF5C "; + std::cout << std::right << std::setw(10) << std::setprecision(5) << std::fixed << this->standard_dev << " \uFF5C "; + //std::cout << std::right << std::setw(10) << std::setprecision(3) << std::fixed << this->totTime * 1000 / this->app->iterations << " \uFF5C "; + std::cout << std::endl; + /*for (int var = 0; var < count; ++var) { + std::cout << std::right << std::setw(10) << std::setprecision(5) << std::fixed << run_time_values[var]<< ";"; + } + std::cout << std::endl;*/ + } vkDeviceWaitIdle(vkh_device_get_vkdev(app->vkhDev)); } - void draw_growing_circles(VkvgContext ctx, float y, int count) { float x = 2; for (int i = 1; i < count; i++) { diff --git a/samples/VkvgTest.hpp b/samples/VkvgTest.hpp index 804abd5..cff6067 100644 --- a/samples/VkvgTest.hpp +++ b/samples/VkvgTest.hpp @@ -43,20 +43,28 @@ typedef void (*VkvgTestFunc)(VkvgTest* test); class VkvgTest { VkvgTestFunc testFunc; + double totTime; + double avg_run_time; + double med_run_time; + double standard_dev; + double avg_frames_per_second; public: static std::vector<VkvgTest*> tests; SampleApp* app; std::string name; + int index; + VkvgTest(VkvgTestFunc testFunc, std::string _name); VkvgDevice device; VkvgSurface surf; + void initTest(SampleApp* app); - void performTest(); - void cleanTest(); + int performTest(int inst); + void cleanTest(double _totTime, double *run_time_values); void draw_random_shape(VkvgContext ctx, shape_t shape, float sizeFact); void draw_random_curve(VkvgContext ctx); diff --git a/samples/tests/clip.cpp b/samples/tests/clip.cpp index bbc3b40..0008dc0 100644 --- a/samples/tests/clip.cpp +++ b/samples/tests/clip.cpp @@ -1,5 +1,5 @@ #include "VkvgTest.hpp" -TEST(clipped_paint_ec) { +TEST(clipped_paint_nz) { VkvgContext ctx = vkvg_create(test->surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); vkvg_set_source_rgb(ctx, 1, 0, 0); @@ -22,7 +22,7 @@ TEST(clipped_paint_eo) { vkvg_destroy(ctx); } -TEST(clipped_paint2_ec) { +TEST(clipped_paint2_nz) { VkvgContext ctx = vkvg_create(test->surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); vkvg_set_source_rgb(ctx, 1, 0, 0); @@ -55,7 +55,7 @@ TEST(clipped_paint2_eo) { vkvg_destroy(ctx); } -TEST(clipped_transformed_ec) { +TEST(clipped_transformed_nz) { VkvgContext ctx = vkvg_create(test->surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); vkvg_set_source_rgb(ctx, 1, 0, 0); @@ -67,7 +67,7 @@ TEST(clipped_transformed_ec) { vkvg_paint(ctx); vkvg_destroy(ctx); } -TEST(clip_transformed_ec) { +TEST(clip_transformed_nz) { VkvgContext ctx = vkvg_create(test->surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); vkvg_set_source_rgb(ctx, 1, 0, 0); @@ -96,9 +96,21 @@ TEST(clipped_transformed_eo) { vkvg_destroy(ctx); } +TEST(clip_clear) { + VkvgContext ctx = vkvg_create(test->surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_paint(ctx); + vkvg_rectangle(ctx, 100, 100, 300, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 1, 0); + vkvg_paint(ctx); + vkvg_destroy(ctx); + +} TEST(test_clip) { VkvgContext ctx = vkvg_create(test->surf); - vkvg_clear(ctx); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); vkvg_move_to(ctx, 10, 10); vkvg_line_to(ctx, 400, 150); @@ -123,7 +135,6 @@ TEST(test_clip) { } TEST(test_clip2) { VkvgContext ctx = vkvg_create(test->surf); - vkvg_clear(ctx); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); vkvg_rectangle(ctx, 50, 50, 500, 500); vkvg_clip(ctx); @@ -166,3 +177,4 @@ TEST(test_clip2) { vkvg_destroy(ctx); } + |