trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From masa...@apache.org
Subject [trafficserver] branch master updated: Micro benchmark tool for global freelist (#8019)
Date Tue, 13 Jul 2021 22:14:40 GMT
This is an automated email from the ASF dual-hosted git repository.

masaori pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new e5ea9fc  Micro benchmark tool for global freelist (#8019)
e5ea9fc is described below

commit e5ea9fc5305110123796abb208c815c331fb6f53
Author: Masaori Koshiba <masaori@apache.org>
AuthorDate: Wed Jul 14 07:14:28 2021 +0900

    Micro benchmark tool for global freelist (#8019)
---
 .gitignore                                  |   1 +
 src/tscore/Makefile.am                      |   6 +-
 src/tscore/unit_tests/freelist_benchmark.cc | 228 ++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 849f3ef..914d1d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,7 @@ src/tscore/CompileParseRules
 src/tscore/ParseRulesCType
 src/tscore/ParseRulesCTypeToLower
 src/tscore/ParseRulesCTypeToUpper
+src/tscore/freelist_benchmark
 src/tscore/mkdfa
 src/tscore/test_atomic
 src/tscore/test_freelist
diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am
index 9610b22..a1cef02 100644
--- a/src/tscore/Makefile.am
+++ b/src/tscore/Makefile.am
@@ -18,7 +18,7 @@
 
 include $(top_srcdir)/build/tidy.mk
 
-noinst_PROGRAMS = mkdfa CompileParseRules
+noinst_PROGRAMS = mkdfa CompileParseRules freelist_benchmark
 check_PROGRAMS = test_geometry test_X509HostnameValidator test_tscore
 
 if EXPENSIVE_TESTS
@@ -199,6 +199,10 @@ test_tscore_SOURCES += \
 	unit_tests/test_HKDF.cc
 endif
 
+freelist_benchmark_CXXFLAGS = -Wno-array-bounds $(AM_CXXFLAGS) -I$(abs_top_srcdir)/tests/include
+freelist_benchmark_LDADD = libtscore.la @HWLOC_LIBS@
+freelist_benchmark_SOURCES = unit_tests/freelist_benchmark.cc
+
 CompileParseRules_SOURCES = CompileParseRules.cc
 
 clean-local:
diff --git a/src/tscore/unit_tests/freelist_benchmark.cc b/src/tscore/unit_tests/freelist_benchmark.cc
new file mode 100644
index 0000000..8ff3e2b
--- /dev/null
+++ b/src/tscore/unit_tests/freelist_benchmark.cc
@@ -0,0 +1,228 @@
+/** @file
+
+  Micro Benchmark tool for global freelist - requires Catch2 v2.9.0+
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#define CATCH_CONFIG_ENABLE_BENCHMARKING
+#define CATCH_CONFIG_RUNNER
+
+#include "catch.hpp"
+
+#include "tscore/ink_thread.h"
+#include "tscore/ink_memory.h"
+#include "tscore/ink_queue.h"
+#include "tscore/hugepages.h"
+
+#include <iostream>
+
+#if TS_USE_HWLOC
+#include <hwloc.h>
+#endif
+
+namespace
+{
+InkFreeList *flist = nullptr;
+
+// Args
+int nloop                 = 1000000;
+int nthreads              = 1;
+int affinity              = 0;
+int thread_assiging_order = 0;
+bool debug_enabled        = false;
+
+#if TS_USE_HWLOC
+hwloc_obj_type_t
+thread_affinity()
+{
+  hwloc_obj_type_t obj_type = HWLOC_OBJ_MACHINE;
+  char const *obj_name      = nullptr;
+
+  switch (affinity) {
+  case 3: {
+    // assign threads to real cores
+    obj_type = HWLOC_OBJ_CORE;
+    obj_name = "Core";
+    break;
+  }
+  case 1: {
+    // assign threads to NUMA nodes (often 1:1 with sockets)
+    obj_type = HWLOC_OBJ_NODE;
+    obj_name = "NUMA Node";
+    if (hwloc_get_nbobjs_by_type(ink_get_topology(), obj_type) > 0) {
+      break;
+    }
+    [[fallthrough]];
+  }
+  case 2: {
+    // assign threads to sockets
+    obj_type = HWLOC_OBJ_SOCKET;
+    obj_name = "Socket";
+    break;
+  }
+  case 4: {
+    // assign threads to logical processing units
+#if HAVE_HWLOC_OBJ_PU
+    // Older versions of libhwloc (eg. Ubuntu 10.04) don't have HWLOC_OBJ_PU.
+    obj_type = HWLOC_OBJ_PU;
+    obj_name = "Logical Processor";
+    break;
+#endif // HAVE_HWLOC_OBJ_PU
+    [[fallthrough]];
+  }
+  default: // assign threads to the machine as a whole (a level below SYSTEM)
+    obj_type = HWLOC_OBJ_MACHINE;
+    obj_name = "Machine";
+  }
+
+  if (debug_enabled) {
+    std::cout << "thread affinity type = " << obj_name << " (" <<
affinity << ")" << std::endl;
+  }
+
+  return obj_type;
+}
+#endif // TS_USE_HWLOC
+
+void *
+test_case_1(void *d)
+{
+  int id;
+  void *m1;
+
+  id = (intptr_t)d;
+
+  for (int i = 0; i < nloop; ++i) {
+    m1 = ink_freelist_new(flist);
+
+    memset(m1, id, 64);
+
+    ink_freelist_free(flist, m1);
+  }
+
+  return nullptr;
+}
+
+void
+setup_test_case_1(const int64_t n)
+{
+  ink_thread list[n];
+
+#if TS_USE_HWLOC
+  // ThreadAffinityInitializer::set_affinity mimics
+  const hwloc_obj_type_t obj_type = thread_affinity();
+  const int obj_count             = hwloc_get_nbobjs_by_type(ink_get_topology(), obj_type);
+
+  assert(obj_count > 0);
+
+  for (int i = 0; i < n; i++) {
+    ink_thread_create(&list[i], test_case_1, (void *)((intptr_t)i), 0, 0, nullptr);
+
+    int dst = i;
+    if (thread_assiging_order == 1) {
+      // Assign threads one side of siblings first
+      dst = i * 2;
+      if (dst >= obj_count) {
+        dst = (i * 2 - obj_count) + 1;
+      }
+    }
+
+    hwloc_obj_t obj = hwloc_get_obj_by_type(ink_get_topology(), obj_type, dst % obj_count);
+    hwloc_set_thread_cpubind(ink_get_topology(), list[i], obj->cpuset, HWLOC_CPUBIND_STRICT);
+
+    if (debug_enabled) {
+      int cpu_mask_len = hwloc_bitmap_snprintf(nullptr, 0, obj->cpuset) + 1;
+      char *cpu_mask   = (char *)alloca(cpu_mask_len);
+      hwloc_bitmap_snprintf(cpu_mask, cpu_mask_len, obj->cpuset);
+
+      std::cout << "tid=" << list[i] << " obj->logical_index=" <<
obj->logical_index << " cpu_mask=" << cpu_mask << std::endl;
+    }
+  }
+#else
+  for (int i = 0; i < n; i++) {
+    ink_thread_create(&list[i], test_case_1, (void *)((intptr_t)i), 0, 0, nullptr);
+  }
+#endif
+
+  for (int i = 0; i < n; i++) {
+    ink_thread_join(list[i]);
+  }
+}
+
+TEST_CASE("simple new and free", "")
+{
+  flist = ink_freelist_create("woof", 64, 256, 8);
+
+  // go 100 times in default (--benchmark-samples)
+  char name[16];
+  snprintf(name, sizeof(name), "nthreads = %d", nthreads);
+  BENCHMARK(name) { return setup_test_case_1(nthreads); };
+}
+} // namespace
+
+int
+main(int argc, char *argv[])
+{
+  Catch::Session session;
+
+  using namespace Catch::clara;
+
+  bool opt_enable_hugepage = false;
+
+  auto cli = session.cli() |
+             Opt(affinity, "type")["--ts-affinity"]("thread affinity type [0-4]\n"
+                                                    "0 = HWLOC_OBJ_MACHINE (default)\n"
+                                                    "1 = HWLOC_OBJ_NODE\n"
+                                                    "2 = HWLOC_OBJ_SOCKET\n"
+                                                    "3 = HWLOC_OBJ_CORE\n"
+                                                    "4 = HWLOC_OBJ_PU") |
+             Opt(nloop, "n")["--ts-nloop"]("number of loop\n"
+                                           "(default: 1000000)") |
+             Opt(nthreads, "n")["--ts-nthreads"]("number of threads\n"
+                                                 "(default: 1)") |
+             Opt(opt_enable_hugepage, "yes|no")["--ts-hugepage"]("enable hugepage\n"
+                                                                 "(default: no)") |
+             Opt(thread_assiging_order, "n")["--ts-thread-order"]("thread assiging order
[0-1]\n"
+                                                                  "0: use both of sibling
of hyper-thread first (default)\n"
+                                                                  "1: use a side of sibling
of hyper-thread first") |
+             Opt(debug_enabled, "yes|no")["--ts-debug"]("enable debuge mode\n");
+
+  session.cli(cli);
+
+  int returnCode = session.applyCommandLine(argc, argv);
+  if (returnCode != 0) {
+    return returnCode;
+  }
+
+  if (debug_enabled) {
+    std::cout << "nloop = " << nloop << std::endl;
+
+    if (opt_enable_hugepage) {
+      std::cout << "hugepage enabled";
+#ifdef MAP_HUGETLB
+      ats_hugepage_init(true);
+      std::cout << " ats_pagesize=" << ats_pagesize();
+      std::cout << " ats_hugepage_size=" << ats_hugepage_size();
+      std::cout << std::endl;
+#else
+      std::cout << "MAP_HUGETLB not defined" << std::endl;
+#endif
+    }
+  }
+
+  return session.run();
+}

Mime
View raw message