[libc-commits] [libc] [libc][math] Improve performance test output (PR #134501)

Tejas Vipin via libc-commits libc-commits at lists.llvm.org
Sat Apr 5 12:13:07 PDT 2025


https://github.com/meltq created https://github.com/llvm/llvm-project/pull/134501

Switches away from "Mine/Other function" to "Function A/B" and prints the names of the actual functions passed on the first line. Also uses ratio of ops per second instead of ratio of average runtime.

>From 6d87fee5fb980121866bc9df4e24d56d987146ee Mon Sep 17 00:00:00 2001
From: meltq <alissxlace at proton.me>
Date: Sat, 5 Apr 2025 16:24:36 +0530
Subject: [PATCH 1/2] Binary op perf output improvement

---
 .../BinaryOpSingleOutputPerf.h                | 51 ++++++++++---------
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h b/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h
index 98a1813bd7b54..8001710d83f5e 100644
--- a/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h
+++ b/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h
@@ -26,7 +26,7 @@ class BinaryOpSingleOutputPerf {
 public:
   typedef OutputType Func(InputType, InputType);
 
-  static void run_perf_in_range(Func myFunc, Func otherFunc,
+  static void run_perf_in_range(Func FuncA, Func FuncB,
                                 StorageType startingBit, StorageType endingBit,
                                 size_t N, size_t rounds, std::ofstream &log) {
     if (sizeof(StorageType) <= sizeof(size_t))
@@ -54,48 +54,48 @@ class BinaryOpSingleOutputPerf {
 
     Timer timer;
     timer.start();
-    runner(myFunc);
+    runner(FuncA);
     timer.stop();
 
-    double my_average = static_cast<double>(timer.nanoseconds()) / N / rounds;
-    log << "-- My function --\n";
+    double a_average = static_cast<double>(timer.nanoseconds()) / N / rounds;
+    log << "-- Function A --\n";
     log << "     Total time      : " << timer.nanoseconds() << " ns \n";
-    log << "     Average runtime : " << my_average << " ns/op \n";
+    log << "     Average runtime : " << a_average << " ns/op \n";
     log << "     Ops per second  : "
-        << static_cast<uint64_t>(1'000'000'000.0 / my_average) << " op/s \n";
+        << static_cast<uint64_t>(1'000'000'000.0 / a_average) << " op/s \n";
 
     timer.start();
-    runner(otherFunc);
+    runner(FuncB);
     timer.stop();
 
-    double other_average =
-        static_cast<double>(timer.nanoseconds()) / N / rounds;
-    log << "-- Other function --\n";
+    double b_average = static_cast<double>(timer.nanoseconds()) / N / rounds;
+    log << "-- Function B --\n";
     log << "     Total time      : " << timer.nanoseconds() << " ns \n";
-    log << "     Average runtime : " << other_average << " ns/op \n";
+    log << "     Average runtime : " << b_average << " ns/op \n";
     log << "     Ops per second  : "
-        << static_cast<uint64_t>(1'000'000'000.0 / other_average) << " op/s \n";
+        << static_cast<uint64_t>(1'000'000'000.0 / b_average) << " op/s \n";
 
-    log << "-- Average runtime ratio --\n";
-    log << "     Mine / Other's  : " << my_average / other_average << " \n";
+    log << "-- Average ops per second ratio --\n";
+    log << "     A / B  : " << b_average / a_average << " \n";
   }
 
-  static void run_perf(Func myFunc, Func otherFunc, int rounds,
-                       const char *logFile) {
+  static void run_perf(Func FuncA, Func FuncB, int rounds, const char *name_a,
+                       const char *name_b, const char *logFile) {
     std::ofstream log(logFile);
+    log << "Function A - " << name_a << " Function B - " << name_b << "\n";
     log << " Performance tests with inputs in denormal range:\n";
-    run_perf_in_range(myFunc, otherFunc, /* startingBit= */ StorageType(0),
+    run_perf_in_range(FuncA, FuncB, /* startingBit= */ StorageType(0),
                       /* endingBit= */ FPBits::max_subnormal().uintval(),
                       1'000'001, rounds, log);
     log << "\n Performance tests with inputs in normal range:\n";
-    run_perf_in_range(myFunc, otherFunc,
+    run_perf_in_range(FuncA, FuncB,
                       /* startingBit= */ FPBits::min_normal().uintval(),
                       /* endingBit= */ FPBits::max_normal().uintval(),
                       1'000'001, rounds, log);
     log << "\n Performance tests with inputs in normal range with exponents "
            "close to each other:\n";
     run_perf_in_range(
-        myFunc, otherFunc,
+        FuncA, FuncB,
         /* startingBit= */ FPBits(OutputType(0x1.0p-10)).uintval(),
         /* endingBit= */ FPBits(OutputType(0x1.0p+10)).uintval(), 1'000'001,
         rounds, log);
@@ -128,21 +128,22 @@ class BinaryOpSingleOutputPerf {
 } // namespace testing
 } // namespace LIBC_NAMESPACE_DECL
 
-#define BINARY_OP_SINGLE_OUTPUT_PERF(OutputType, InputType, myFunc, otherFunc, \
+#define BINARY_OP_SINGLE_OUTPUT_PERF(OutputType, InputType, FuncA, FuncB,      \
                                      filename)                                 \
   int main() {                                                                 \
     LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<                         \
-        OutputType, InputType>::run_perf(&myFunc, &otherFunc, 1, filename);    \
+        OutputType, InputType>::run_perf(&FuncA, &FuncB, 1, #FuncA, #FuncB,    \
+                                         filename);                            \
     return 0;                                                                  \
   }
 
-#define BINARY_OP_SINGLE_OUTPUT_PERF_EX(OutputType, InputType, myFunc,         \
-                                        otherFunc, rounds, filename)           \
+#define BINARY_OP_SINGLE_OUTPUT_PERF_EX(OutputType, InputType, FuncA, FuncB,   \
+                                        rounds, filename)                      \
   {                                                                            \
     LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<                         \
-        OutputType, InputType>::run_perf(&myFunc, &otherFunc, rounds,          \
+        OutputType, InputType>::run_perf(&FuncA, &FuncB, 1, #FuncA, #FuncB,    \
                                          filename);                            \
     LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<                         \
-        OutputType, InputType>::run_perf(&myFunc, &otherFunc, rounds,          \
+        OutputType, InputType>::run_perf(&FuncA, &FuncB, 1, #FuncA, #FuncB,    \
                                          filename);                            \
   }

>From 441efdf9b6f5b8385b34768b484ac1b870256a77 Mon Sep 17 00:00:00 2001
From: meltq <alissxlace at proton.me>
Date: Sat, 5 Apr 2025 23:26:24 +0530
Subject: [PATCH 2/2] Single input perf output improvement

---
 .../SingleInputSingleOutputPerf.h             | 43 ++++++++++---------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/libc/test/src/math/performance_testing/SingleInputSingleOutputPerf.h b/libc/test/src/math/performance_testing/SingleInputSingleOutputPerf.h
index efad1259d6bf1..93c217de250e6 100644
--- a/libc/test/src/math/performance_testing/SingleInputSingleOutputPerf.h
+++ b/libc/test/src/math/performance_testing/SingleInputSingleOutputPerf.h
@@ -25,7 +25,7 @@ template <typename T> class SingleInputSingleOutputPerf {
 public:
   typedef T Func(T);
 
-  static void runPerfInRange(Func myFunc, Func otherFunc,
+  static void runPerfInRange(Func FuncA, Func FuncB,
                              StorageType startingBit, StorageType endingBit,
                              size_t rounds, std::ofstream &log) {
     size_t n = 10'010'001;
@@ -47,40 +47,41 @@ template <typename T> class SingleInputSingleOutputPerf {
 
     Timer timer;
     timer.start();
-    runner(myFunc);
+    runner(FuncA);
     timer.stop();
 
-    double myAverage = static_cast<double>(timer.nanoseconds()) / n / rounds;
-    log << "-- My function --\n";
+    double a_average = static_cast<double>(timer.nanoseconds()) / n / rounds;
+    log << "-- Function A --\n";
     log << "     Total time      : " << timer.nanoseconds() << " ns \n";
-    log << "     Average runtime : " << myAverage << " ns/op \n";
+    log << "     Average runtime : " << a_average << " ns/op \n";
     log << "     Ops per second  : "
-        << static_cast<uint64_t>(1'000'000'000.0 / myAverage) << " op/s \n";
+        << static_cast<uint64_t>(1'000'000'000.0 / a_average) << " op/s \n";
 
     timer.start();
-    runner(otherFunc);
+    runner(FuncB);
     timer.stop();
 
-    double otherAverage = static_cast<double>(timer.nanoseconds()) / n / rounds;
-    log << "-- Other function --\n";
+    double b_average = static_cast<double>(timer.nanoseconds()) / n / rounds;
+    log << "-- Function B --\n";
     log << "     Total time      : " << timer.nanoseconds() << " ns \n";
-    log << "     Average runtime : " << otherAverage << " ns/op \n";
+    log << "     Average runtime : " << b_average << " ns/op \n";
     log << "     Ops per second  : "
-        << static_cast<uint64_t>(1'000'000'000.0 / otherAverage) << " op/s \n";
+        << static_cast<uint64_t>(1'000'000'000.0 / b_average) << " op/s \n";
 
-    log << "-- Average runtime ratio --\n";
-    log << "     Mine / Other's  : " << myAverage / otherAverage << " \n";
+    log << "-- Average ops per second ratio --\n";
+    log << "     A / B  : " << b_average / a_average << " \n";
   }
 
-  static void runPerf(Func myFunc, Func otherFunc, size_t rounds,
-                      const char *logFile) {
+  static void runPerf(Func FuncA, Func FuncB, size_t rounds, const char *name_a,
+                      const char *name_b, const char *logFile) {
     std::ofstream log(logFile);
+    log << "Function A - " << name_a << " Function B - " << name_b << "\n";
     log << " Performance tests with inputs in denormal range:\n";
-    runPerfInRange(myFunc, otherFunc, /* startingBit= */ StorageType(0),
+    runPerfInRange(FuncA, FuncB, /* startingBit= */ StorageType(0),
                    /* endingBit= */ FPBits::max_subnormal().uintval(), rounds,
                    log);
     log << "\n Performance tests with inputs in normal range:\n";
-    runPerfInRange(myFunc, otherFunc,
+    runPerfInRange(FuncA, FuncB,
                    /* startingBit= */ FPBits::min_normal().uintval(),
                    /* endingBit= */ FPBits::max_normal().uintval(), rounds,
                    log);
@@ -90,16 +91,16 @@ template <typename T> class SingleInputSingleOutputPerf {
 } // namespace testing
 } // namespace LIBC_NAMESPACE_DECL
 
-#define SINGLE_INPUT_SINGLE_OUTPUT_PERF(T, myFunc, otherFunc, filename)        \
+#define SINGLE_INPUT_SINGLE_OUTPUT_PERF(T, FuncA, FuncB, filename)             \
   int main() {                                                                 \
     LIBC_NAMESPACE::testing::SingleInputSingleOutputPerf<T>::runPerf(          \
-        &myFunc, &otherFunc, 1, filename);                                     \
+        &FuncA, &FuncB, 1, #FuncA, #FuncB, filename);                          \
     return 0;                                                                  \
   }
 
-#define SINGLE_INPUT_SINGLE_OUTPUT_PERF_EX(T, myFunc, otherFunc, rounds,       \
+#define SINGLE_INPUT_SINGLE_OUTPUT_PERF_EX(T, FuncA, FuncB, rounds,            \
                                            filename)                           \
   {                                                                            \
     LIBC_NAMESPACE::testing::SingleInputSingleOutputPerf<T>::runPerf(          \
-        &myFunc, &otherFunc, rounds, filename);                                \
+        &FuncA, &FuncB, rounds, #FuncA, #FuncB, filename);                     \
   }



More information about the libc-commits mailing list