[glib/3v1n0/allocation-benchmarks: 28/30] tests: Add simple allocating benchmark with both system and slice allocator




commit 8f50feb4ef0c8b69cf630351823af048b20b94d9
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Thu Jul 7 16:46:47 2022 +0200

    tests: Add simple allocating benchmark with both system and slice allocator

 meson.build              |  25 +++++
 tests/allocators-tests.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 266 insertions(+)
---
diff --git a/meson.build b/meson.build
index 0edbc2bf00..4b38007fdb 100644
--- a/meson.build
+++ b/meson.build
@@ -2389,5 +2389,30 @@ if get_option('man')
   man1_dir = join_paths(glib_prefix, get_option('mandir'), 'man1')
 endif
 
+
+allocate_system = executable('allocators-test-system',
+  'tests/allocators-tests.c',
+  c_args: [
+    '-DG_LOG_DOMAIN="GLib-Benchmark"',
+    '-UG_DISABLE_ASSERT',
+    '-DG_USE_SYSTEM_ALLOCATOR',
+  ],
+  dependencies: libglib_dep,
+  install: false
+)
+
+allocate_gslice = executable('allocators-test-gslice',
+  'tests/allocators-tests.c',
+  c_args: [
+    '-DG_LOG_DOMAIN="GLib-Benchmark"',
+    '-UG_DISABLE_ASSERT',
+  ],
+  dependencies: [libglib_dep],
+  install: false
+)
+
+benchmark('allocate-system', allocate_system, timeout: 1000)
+benchmark('allocate-gslice', allocate_gslice, timeout: 1000)
+
 gnome = import('gnome')
 subdir('docs/reference')
diff --git a/tests/allocators-tests.c b/tests/allocators-tests.c
new file mode 100644
index 0000000000..f17dfa7851
--- /dev/null
+++ b/tests/allocators-tests.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2022 Canonical Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Marco Trevisan <marco trevisan canonical com>
+ */
+
+#include <glib.h>
+
+/* These are to please CI, should be adjusted smartly */
+#define SIMPLE_TYPE_ITERATIONS 100000000
+#if defined(G_OS_UNIX) && !__APPLE__
+#define POINTERS_ARRAY_SIZE 1000000
+#elif defined(__APPLE__)
+#define POINTERS_ARRAY_SIZE 100000
+#else
+#define POINTERS_ARRAY_SIZE 10000
+#endif
+#define MAX_ALLOCATED_SIZE (POINTERS_ARRAY_SIZE * 512)
+
+#ifdef G_USE_SYSTEM_ALLOCATOR
+#define instance_alloc(s) g_malloc ((s))
+#define instance_alloc0(s) g_malloc0 ((s))
+#define instance_free(s, p) g_free ((p))
+#else
+#define instance_alloc(s) g_slice_alloc ((s))
+#define instance_alloc0(s) g_slice_alloc0 ((s))
+#define instance_free(s, p) g_slice_free1 ((s), (p))
+#endif
+
+#define allocate_and_free_many(type, type_size, allocator, N) \
+  {                                                           \
+    guint i;                                                  \
+                                                              \
+    for (i = 0; i < N; i++)                                   \
+      {                                                       \
+        gpointer ptr = allocator (type_size);                 \
+        instance_free (type_size, ptr);                       \
+      }                                                       \
+  }
+
+#define test_alloc_and_free(type, type_size, allocator, N)                           \
+  {                                                                                  \
+    gdouble time_elapsed;                                                            \
+                                                                                     \
+    g_test_timer_start ();                                                           \
+                                                                                     \
+    allocate_and_free_many (type, type_size, allocator, N);                          \
+                                                                                     \
+    time_elapsed = g_test_timer_elapsed ();                                          \
+    g_test_minimized_result (time_elapsed,                                           \
+                             "Allocated and free'd %u instances of %s "              \
+                             "(size: %" G_GSIZE_FORMAT " using %s in %6.5f seconds", \
+                             N, #type, (gsize) type_size, #allocator, time_elapsed); \
+  }
+
+#define test_alloc_many_and_free(type, type_size, allocator, N)                      \
+  {                                                                                  \
+    guint i;                                                                         \
+    gdouble time_elapsed;                                                            \
+    gpointer *ptrs[N] = { 0 };                                                       \
+    gdouble total_time = 0;                                                          \
+                                                                                     \
+    g_test_timer_start ();                                                           \
+                                                                                     \
+    for (i = 0; i < N; i++)                                                          \
+      ptrs[i] = allocator (type_size);                                               \
+                                                                                     \
+    time_elapsed = g_test_timer_elapsed ();                                          \
+    total_time += time_elapsed;                                                      \
+                                                                                     \
+    g_test_minimized_result (time_elapsed,                                           \
+                             "Allocated %u instances of %s (size: %" G_GSIZE_FORMAT  \
+                             ") using %s in %6.5f seconds",                          \
+                             N, #type, (gsize) type_size, #allocator, time_elapsed); \
+                                                                                     \
+    g_test_timer_start ();                                                           \
+                                                                                     \
+    for (i = 0; i < N; i++)                                                          \
+      instance_free (type_size, ptrs[i]);                                            \
+                                                                                     \
+    time_elapsed = g_test_timer_elapsed ();                                          \
+    total_time += time_elapsed;                                                      \
+                                                                                     \
+    g_test_minimized_result (time_elapsed,                                           \
+                             "Free'd %u instances of %s in %6.5f seconds",           \
+                             N, #type, time_elapsed);                                \
+    g_test_minimized_result (total_time,                                             \
+                             "Allocated and Free'd %u instances of %s using %s "     \
+                             "in %6.5f seconds",                                     \
+                             N, #type, #allocator, total_time);                      \
+  }
+
+#define test_allocation_simple_type(type)                                                 \
+  static void                                                                             \
+      test_allocation_##type (void)                                                       \
+  {                                                                                       \
+    test_alloc_and_free (type, sizeof (type), instance_alloc, SIMPLE_TYPE_ITERATIONS);    \
+    test_alloc_and_free (type, sizeof (type), instance_alloc0, SIMPLE_TYPE_ITERATIONS);   \
+                                                                                          \
+    test_alloc_many_and_free (type, sizeof (type), instance_alloc, POINTERS_ARRAY_SIZE);  \
+    test_alloc_many_and_free (type, sizeof (type), instance_alloc0, POINTERS_ARRAY_SIZE); \
+  }
+
+#define test_allocation_sized(size)                                                      \
+  static void                                                                            \
+      test_allocation_sized_##size (void)                                                \
+  {                                                                                      \
+    test_alloc_and_free ("struct" #size, size, instance_alloc, SIMPLE_TYPE_ITERATIONS);  \
+    test_alloc_and_free ("struct" #size, size, instance_alloc0, SIMPLE_TYPE_ITERATIONS); \
+                                                                                         \
+    test_alloc_many_and_free ("struct" #size, size, instance_alloc,                      \
+                              MIN (POINTERS_ARRAY_SIZE, MAX_ALLOCATED_SIZE / size));     \
+    test_alloc_many_and_free ("struct" #size, size, instance_alloc0,                     \
+                              MIN (POINTERS_ARRAY_SIZE, MAX_ALLOCATED_SIZE / size));     \
+  }
+
+#define test_allocate_and_free_many_mixed(max_steps, allocator, N)                    \
+  {                                                                                   \
+    guint i;                                                                          \
+    gdouble time_elapsed;                                                             \
+    GArray *steps_size = g_array_sized_new (FALSE, FALSE, sizeof (gsize), max_steps); \
+                                                                                      \
+    for (i = 0; i < max_steps; i++)                                                   \
+      {                                                                               \
+        gsize size = 1 << (i + 1);                                                    \
+        if (g_test_verbose ())                                                        \
+          g_test_message ("Step allocation size %" G_GSIZE_FORMAT, size);             \
+        g_array_insert_val (steps_size, i, size);                                     \
+      }                                                                               \
+                                                                                      \
+    g_test_timer_start ();                                                            \
+                                                                                      \
+    for (i = 0; i < N; i++)                                                           \
+      {                                                                               \
+        gsize element_size = g_array_index (steps_size, gsize, (i % max_steps));      \
+        gpointer ptr = allocator (element_size);                                      \
+        instance_free (element_size, ptr);                                            \
+      }                                                                               \
+                                                                                      \
+    time_elapsed = g_test_timer_elapsed ();                                           \
+    g_test_minimized_result (time_elapsed,                                            \
+                             "Allocated and free'd %u instances of mixed types "      \
+                             "(step: %s) using %s in %6.5f seconds",                  \
+                             N, #max_steps, #allocator, time_elapsed);                \
+  }
+
+#define test_allocation_mixed_sizes(max_steps)                     \
+  static void                                                      \
+      test_allocation_mixed_step_##max_steps (void)                \
+  {                                                                \
+    gsize step_size = 0;                                           \
+    gint i;                                                        \
+                                                                   \
+    for (i = 0; i < max_steps; i++)                                \
+      step_size += 1 << (i + 1);                                   \
+    (void) step_size;                                              \
+                                                                   \
+    test_allocate_and_free_many_mixed (max_steps, instance_alloc,  \
+                                       SIMPLE_TYPE_ITERATIONS);    \
+    test_allocate_and_free_many_mixed (max_steps, instance_alloc0, \
+                                       SIMPLE_TYPE_ITERATIONS);    \
+  }
+
+test_allocation_simple_type (gchar);
+test_allocation_simple_type (gshort);
+test_allocation_simple_type (glong);
+test_allocation_simple_type (gint);
+test_allocation_simple_type (gboolean);
+test_allocation_simple_type (guchar);
+test_allocation_simple_type (gushort);
+test_allocation_simple_type (gulong);
+test_allocation_simple_type (guint);
+test_allocation_simple_type (gfloat);
+test_allocation_simple_type (gdouble);
+test_allocation_simple_type (gpointer);
+
+test_allocation_sized (32);
+test_allocation_sized (64);
+test_allocation_sized (128);
+test_allocation_sized (256);
+test_allocation_sized (512);
+test_allocation_sized (1024);
+test_allocation_sized (2048);
+test_allocation_sized (4096);
+
+test_allocation_mixed_sizes (8);
+test_allocation_mixed_sizes (12);
+
+#ifdef G_USE_SYSTEM_ALLOCATOR
+#define TEST_BASENAME "/allocation/system"
+#else
+#define TEST_BASENAME "/allocation/gslice"
+#endif
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func (TEST_BASENAME "/simple-type/gchar", test_allocation_gchar);
+  g_test_add_func (TEST_BASENAME "/simple-type/gshort", test_allocation_gshort);
+  g_test_add_func (TEST_BASENAME "/simple-type/glong", test_allocation_glong);
+  g_test_add_func (TEST_BASENAME "/simple-type/gint", test_allocation_gint);
+  g_test_add_func (TEST_BASENAME "/simple-type/gboolean", test_allocation_gboolean);
+  g_test_add_func (TEST_BASENAME "/simple-type/guchar", test_allocation_guchar);
+  g_test_add_func (TEST_BASENAME "/simple-type/gushort", test_allocation_gushort);
+  g_test_add_func (TEST_BASENAME "/simple-type/gulong", test_allocation_gulong);
+  g_test_add_func (TEST_BASENAME "/simple-type/guint", test_allocation_guint);
+  g_test_add_func (TEST_BASENAME "/simple-type/gfloat", test_allocation_gfloat);
+  g_test_add_func (TEST_BASENAME "/simple-type/gdouble", test_allocation_gdouble);
+  g_test_add_func (TEST_BASENAME "/simple-type/gpointer", test_allocation_gpointer);
+
+  g_test_add_func (TEST_BASENAME "/sized/32", test_allocation_sized_32);
+  g_test_add_func (TEST_BASENAME "/sized/64", test_allocation_sized_64);
+  g_test_add_func (TEST_BASENAME "/sized/128", test_allocation_sized_128);
+  g_test_add_func (TEST_BASENAME "/sized/256", test_allocation_sized_256);
+  g_test_add_func (TEST_BASENAME "/sized/512", test_allocation_sized_512);
+  g_test_add_func (TEST_BASENAME "/sized/1024", test_allocation_sized_1024);
+  g_test_add_func (TEST_BASENAME "/sized/2048", test_allocation_sized_2048);
+  g_test_add_func (TEST_BASENAME "/sized/4096", test_allocation_sized_4096);
+
+  g_test_add_func (TEST_BASENAME "/mixed/8", test_allocation_mixed_step_8);
+  g_test_add_func (TEST_BASENAME "/mixed/12", test_allocation_mixed_step_12);
+
+  return g_test_run ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]