summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-07-10 10:55:13 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-09-04 11:06:23 +0200
commitc212b34cc12c69fd380e0b1a2ed3bbf41826345d (patch)
treed6aa97767eea2049ca195934e539dc6594e26cbc
parent78092ce771c506873b2839b70ad7c488a01535c3 (diff)
add time measure in samples
-rw-r--r--samples/SampleApp.cpp33
-rw-r--r--samples/SampleApp.hpp16
-rw-r--r--samples/VkvgTest.cpp54
-rw-r--r--samples/VkvgTest.hpp12
-rw-r--r--samples/tests/clip.cpp24
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);
}
+