This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 9148fb97186196778ea0efa5f083ecb630e4287d
Author: makejian <[email protected]>
AuthorDate: Tue Jan 20 10:29:56 2026 +0800

    benchmarks: Add Whetstone FPU benchmark
    
    Add the Whetstone floating-point benchmark to NuttX applications.
    The Whetstone benchmark is a widely-used tool for evaluating FPU
    (floating-point unit) performance.
    
    This benchmark is ported from netlib.org whetstone.c which has a
    custom permissive license requiring attribution. Therefore it
    depends on ALLOW_CUSTOM_PERMISSIVE_COMPONENTS.
    
    Usage: whetstone [loops]
    
    Signed-off-by: makejian <[email protected]>
---
 benchmarks/whetstone/CMakeLists.txt |  31 +++
 benchmarks/whetstone/Kconfig        |  34 +++
 benchmarks/whetstone/Make.defs      |  23 ++
 benchmarks/whetstone/Makefile       |  32 +++
 benchmarks/whetstone/whetstone.c    | 517 ++++++++++++++++++++++++++++++++++++
 5 files changed, 637 insertions(+)

diff --git a/benchmarks/whetstone/CMakeLists.txt 
b/benchmarks/whetstone/CMakeLists.txt
new file mode 100644
index 000000000..1bcc0f256
--- /dev/null
+++ b/benchmarks/whetstone/CMakeLists.txt
@@ -0,0 +1,31 @@
+# 
##############################################################################
+# apps/benchmarks/whetstone/CMakeLists.txt
+#
+# 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.
+#
+# 
##############################################################################
+
+if(CONFIG_BENCHMARK_WHETSTONE)
+  nuttx_add_application(
+    NAME
+    ${CONFIG_BENCHMARK_WHETSTONE_PROGNAME}
+    SRCS
+    whetstone.c
+    STACKSIZE
+    ${CONFIG_BENCHMARK_WHETSTONE_STACKSIZE}
+    PRIORITY
+    ${CONFIG_BENCHMARK_WHETSTONE_PRIORITY})
+endif()
diff --git a/benchmarks/whetstone/Kconfig b/benchmarks/whetstone/Kconfig
new file mode 100644
index 000000000..10df1429e
--- /dev/null
+++ b/benchmarks/whetstone/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config BENCHMARK_WHETSTONE
+       tristate "Double Precision Benchmark"
+       default n
+       depends on ALLOW_CUSTOM_PERMISSIVE_COMPONENTS
+       ---help---
+               Enable a Whetstone test.
+
+               This benchmark is based on the C converted version from
+               https://www.netlib.org/benchmark/whetstone.c which has a
+               custom permissive license requiring attribution.
+
+if BENCHMARK_WHETSTONE
+
+config BENCHMARK_WHETSTONE_PROGNAME
+       string "Program name"
+       default "whetstone"
+       ---help---
+               This is the name of the program that will be used when the NSH 
ELF
+               program is installed.
+
+config BENCHMARK_WHETSTONE_PRIORITY
+       int "Whetstone test task priority"
+       default 100
+
+config BENCHMARK_WHETSTONE_STACKSIZE
+       int "Whetstone test stack size"
+       default DEFAULT_TASK_STACKSIZE
+
+endif
diff --git a/benchmarks/whetstone/Make.defs b/benchmarks/whetstone/Make.defs
new file mode 100644
index 000000000..d9fa9f1af
--- /dev/null
+++ b/benchmarks/whetstone/Make.defs
@@ -0,0 +1,23 @@
+############################################################################
+# apps/benchmarks/whetstone/Make.defs
+#
+# 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.
+#
+############################################################################
+
+ifneq ($(CONFIG_BENCHMARK_WHETSTONE),)
+CONFIGURED_APPS += $(APPDIR)/benchmarks/whetstone
+endif
diff --git a/benchmarks/whetstone/Makefile b/benchmarks/whetstone/Makefile
new file mode 100644
index 000000000..1bdf6dfd6
--- /dev/null
+++ b/benchmarks/whetstone/Makefile
@@ -0,0 +1,32 @@
+############################################################################
+# apps/benchmarks/whetstone/Makefile
+#
+# 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.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+# WHETSTONE speed test
+
+PROGNAME = $(CONFIG_BENCHMARK_WHETSTONE_PROGNAME)
+PRIORITY = $(CONFIG_BENCHMARK_WHETSTONE_PRIORITY)
+STACKSIZE = $(CONFIG_BENCHMARK_WHETSTONE_STACKSIZE)
+MODULE = $(CONFIG_BENCHMARK_WHETSTONE)
+
+MAINSRC = whetstone.c
+
+include $(APPDIR)/Application.mk
diff --git a/benchmarks/whetstone/whetstone.c b/benchmarks/whetstone/whetstone.c
new file mode 100644
index 000000000..4363baaf7
--- /dev/null
+++ b/benchmarks/whetstone/whetstone.c
@@ -0,0 +1,517 @@
+/****************************************************************************
+ * apps/benchmarks/whetstone/whetstone.c
+ *
+ * SPDX-License-Identifier: LicenseRef-Painter-Engineering-Whetstone
+ *
+ * Converted Whetstone Double Precision Benchmark
+ *    Version 1.2  22 March 1998
+ *
+ *  (c) Copyright 1998 Painter Engineering, Inc.
+ *    All Rights Reserved.
+ *
+ *    Permission is granted to use, duplicate, and
+ *    publish this text and program as long as it
+ *    includes this entire comment block and limited
+ *    rights reference.
+ *
+ * Converted by Rich Painter, Painter Engineering, Inc. based on the
+ * www.netlib.org benchmark/whetstoned version obtained 16 March 1998.
+ *
+ * A novel approach was used here to keep the look and feel of the
+ * FORTRAN version.  Altering the FORTRAN-based array indices,
+ * starting at element 1, to start at element 0 for C, would require
+ * numerous changes, including decrementing the variable indices by 1.
+ * Instead, the array e1[] was declared 1 element larger in C.  This
+ * allows the FORTRAN index range to function without any literal or
+ * variable indices changes.  The array element e1[0] is simply never
+ * used and does not alter the benchmark results.
+ *
+ * The major FORTRAN comment blocks were retained to minimize
+ * differences between versions.  Modules N5 and N12, like in the
+ * FORTRAN version, have been eliminated here.
+ *
+ * An optional command-line argument has been provided [-c] to
+ * offer continuous repetition of the entire benchmark.
+ * An optional argument for setting an alternate loop count is also
+ * provided.  Define PRINTOUT to cause the pout() function to print
+ * outputs at various stages.  Final timing measurements should be
+ * made with the PRINTOUT undefined.
+ *
+ * Questions and comments may be directed to the author at
+ *      [email protected]
+ ****************************************************************************/
+
+/****************************************************************************
+ *     Benchmark #2 -- Double  Precision Whetstone (A001)
+ *
+ *     o  This is a REAL*8 version of
+ *  the Whetstone benchmark program.
+ *
+ *     o  DO-loop semantics are ANSI-66 compatible.
+ *
+ *     o  Final measurements are to be made with all
+ *  WRITE statements and FORMAT sttements removed.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/* standard C library headers required */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/* the following is optional depending on the timing function used */
+
+#include <time.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* map the FORTRAN math functions, etc. to the C versions */
+
+#define DSIN  sin
+#define DCOS  cos
+#define DATAN  atan
+#define DLOG  log
+#define DEXP  exp
+#define DSQRT  sqrt
+#define IF    if
+#define USAGE  "usage: whetdc [-c] [loops]\n"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* function prototypes */
+
+void pout(long n, long j, long k, double x1,
+          double x2, double x3, double x4);
+void pa(double e[]);
+void p0(void);
+void p3(double x, double y, FAR double *z);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* COMMON t,t1,t2,e1(4),j,k,l */
+
+double t;
+double t1;
+double t2;
+double e1[5];
+int j;
+int k;
+int l;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  /* used in the FORTRAN version */
+
+  long loop;
+  long i;
+  long n1;
+  long n2;
+  long n3;
+  long n4;
+  long n6;
+  long n7;
+  long n8;
+  long n9;
+  long n10;
+  long n11;
+  double x1;
+  double x2;
+  double x3;
+  double x4;
+  double x;
+  double y;
+  double z;
+  int ii;
+  int jj;
+
+  /* added for this version */
+
+  long loopstart;
+  long startsec;
+  long finisec;
+  float KIPS;
+  int continuous;
+
+  loopstart = 1000;    /* see the note about loop below */
+  continuous = 0;
+
+  ii = 1;    /* start at the first arg (temp use of ii here) */
+  while (ii < argc)
+    {
+      if (strncmp(argv[ii], "-c", 2) == 0 || argv[ii][0] == 'c')
+        {
+          continuous = 1;
+        }
+      else if (atol(argv[ii]) > 0)
+        {
+          loopstart = atol(argv[ii]);
+        }
+      else
+        {
+          fprintf(stderr, USAGE);
+          return 1;
+        }
+
+      ii++;
+    }
+
+LCONT:
+
+  /* Start benchmark timing at this point. */
+
+  startsec = time(0);
+
+  /* The actual benchmark starts here. */
+
+  t  = .499975;
+  t1 = 0.50025;
+  t2 = 2.0;
+
+  /* With loopcount loop=10, one million Whetstone instructions
+   * will be executed in EACH MAJOR loop..A MAJOR loop IS EXECUTED
+   * 'ii' TIMES TO INCREASE WALL-CLOCK TIMING ACCURACY.
+   *
+   * loop = 1000;
+   */
+
+  loop = loopstart;
+  ii   = 1;
+
+  jj = 1;
+
+IILOOP:
+  n1  = 0;
+  n2  = 12 * loop;
+  n3  = 14 * loop;
+  n4  = 345 * loop;
+  n6  = 210 * loop;
+  n7  = 32 * loop;
+  n8  = 899 * loop;
+  n9  = 616 * loop;
+  n10 = 0;
+  n11 = 93 * loop;
+
+  /* Module 1: Simple identifiers */
+
+  x1  =  1.0;
+  x2  = -1.0;
+  x3  = -1.0;
+  x4  = -1.0;
+
+  for (i = 1; i <= n1; i++)
+    {
+      x1 = (x1 + x2 + x3 - x4) * t;
+      x2 = (x1 + x2 - x3 + x4) * t;
+      x3 = (x1 - x2 + x3 + x4) * t;
+      x4 = (-x1 + x2 + x3 + x4) * t;
+    }
+
+#ifdef PRINTOUT
+  IF (jj  ==  ii)
+    {
+      pout(n1, n1, n1, x1, x2, x3, x4);
+    }
+#endif
+
+  /* Module 2: Array elements */
+
+  e1[1] =  1.0;
+  e1[2] = -1.0;
+  e1[3] = -1.0;
+  e1[4] = -1.0;
+
+  for (i = 1; i <= n2; i++)
+    {
+      e1[1] = (e1[1] + e1[2] + e1[3] - e1[4]) * t;
+      e1[2] = (e1[1] + e1[2] - e1[3] + e1[4]) * t;
+      e1[3] = (e1[1] - e1[2] + e1[3] + e1[4]) * t;
+      e1[4] = (-e1[1] + e1[2] + e1[3] + e1[4]) * t;
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n2, n3, n2, e1[1], e1[2], e1[3], e1[4]);
+    }
+#endif
+
+  /* Module 3: Array as parameter */
+
+  for (i = 1; i <= n3; i++)
+    {
+      pa(e1);
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n3, n2, n2, e1[1], e1[2], e1[3], e1[4]);
+    }
+#endif
+
+  /* Module 4: Conditional jumps */
+
+  j = 1;
+  for (i = 1; i <= n4; i++)
+    {
+      if (j == 1)
+        {
+          j = 2;
+        }
+      else
+        {
+          j = 3;
+        }
+
+      if (j > 2)
+        {
+          j = 0;
+        }
+      else
+        {
+          j = 1;
+        }
+
+      if (j < 1)
+        {
+          j = 1;
+        }
+      else
+        {
+          j = 0;
+        }
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n4, j, j, x1, x2, x3, x4);
+    }
+#endif
+
+/* Module 5: Omitted
+ * Module 6: Integer arithmetic
+ */
+
+  j = 1;
+  k = 2;
+  l = 3;
+
+  for (i = 1; i <= n6; i++)
+    {
+      j = j * (k - j) * (l - k);
+      k = l * k - (l - j) * k;
+      l = (l - k) * (k + j);
+      e1[l - 1] = j + k + l;
+      e1[k - 1] = j * k * l;
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n6, j, k, e1[1], e1[2], e1[3], e1[4]);
+    }
+#endif
+
+  /* Module 7: Trigonometric functions */
+
+  x = 0.5;
+  y = 0.5;
+
+  for (i = 1; i <= n7; i++)
+    {
+      x = t * DATAN(t2 * DSIN(x) * DCOS(x) /
+             (DCOS(x + y) + DCOS(x - y) - 1.0));
+      y = t * DATAN(t2 * DSIN(y) * DCOS(y) /
+             (DCOS(x + y) + DCOS(x - y) - 1.0));
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n7, j, k, x, x, y, y);
+    }
+#endif
+
+  /* Module 8: Procedure calls */
+
+  x = 1.0;
+  y = 1.0;
+  z = 1.0;
+
+  for (i = 1; i <= n8; i++)
+    {
+      p3(x, y, &z);
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n8, j, k, x, y, z, z);
+    }
+#endif
+
+  /* Module 9: Array references */
+
+  j = 1;
+  k = 2;
+  l = 3;
+  e1[1] = 1.0;
+  e1[2] = 2.0;
+  e1[3] = 3.0;
+
+  for (i = 1; i <= n9; i++)
+    {
+      p0();
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n9, j, k, e1[1], e1[2], e1[3], e1[4]);
+    }
+#endif
+
+  /* Module 10: Integer arithmetic */
+
+  j = 2;
+  k = 3;
+
+  for (i = 1; i <= n10; i++)
+    {
+      j = j + k;
+      k = j + k;
+      j = k - j;
+      k = k - j - j;
+    }
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n10, j, k, x1, x2, x3, x4);
+    }
+#endif
+
+  /* Module 11: Standard functions */
+
+  x = 0.75;
+
+  for (i = 1; i <= n11; i++)
+    x = DSQRT(DEXP(DLOG(x) / t1));
+
+#ifdef PRINTOUT
+  IF (jj == ii)
+    {
+      pout(n11, j, k, x, x, x, x);
+    }
+#endif
+
+  /* THIS IS THE END OF THE MAJOR loop. */
+
+  if (++jj <= ii)
+    {
+      goto IILOOP;
+    }
+
+  /* Stop benchmark timing at this point. */
+
+  finisec = time(0);
+
+  /* Performance in Whetstone KIP's per second is given by
+   *
+   * (100*loop*ii)/TIME
+   *
+   * where TIME is in seconds.
+   */
+
+  printf("\n");
+  if (finisec - startsec <= 0)
+    {
+      printf("Insufficient duration- Increase the loop count\n");
+      return 1;
+    }
+
+  printf("Loops: %ld, Iterations: %d, Duration: %ld sec.\n",
+                                loop, ii, finisec - startsec);
+
+  KIPS = (100.0 * loop * ii) / (float)(finisec - startsec);
+  if (KIPS >= 1000.0)
+    {
+      printf("C Converted Double Precision Whetstones: %.1f MIPS\n",
+                                                     KIPS / 1000.0);
+    }
+  else
+    {
+      printf("C Converted Double Precision Whetstones: %.1f KIPS\n", KIPS);
+    }
+
+  if (continuous)
+    {
+      goto LCONT;
+    }
+
+  return 0;
+}
+
+void
+pa(double e[])
+{
+  j = 0;
+
+L10:
+  e[1] = (e[1] + e[2] + e[3] - e[4]) * t;
+  e[2] = (e[1] + e[2] - e[3] + e[4]) * t;
+  e[3] = (e[1] - e[2] + e[3] + e[4]) * t;
+  e[4] = (-e[1] + e[2] + e[3] + e[4]) / t2;
+  j += 1;
+
+  if (j < 6)
+    {
+      goto L10;
+    }
+}
+
+void
+p0(void)
+{
+  e1[j] = e1[k];
+  e1[k] = e1[l];
+  e1[l] = e1[j];
+}
+
+void p3(double x, double y, FAR double *z)
+{
+  double x1;
+  double y1;
+
+  x1 = x;
+  y1 = y;
+  x1 = t * (x1 + y1);
+  y1 = t * (x1 + y1);
+  *z  = (x1 + y1) / t2;
+}
+
+#ifdef PRINTOUT
+void
+pout(long n, long j, long k, double x1, double x2, double x3, double x4)
+{
+  printf("%7ld %7ld %7ld %12.4e %12.4e %12.4e %12.4e\n",
+            n, j, k, x1, x2, x3, x4);
+}
+#endif

Reply via email to