This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ping][PATCH] Allow multiple input domains to be run in the same benchmark program


Ping!

On Wed, Apr 24, 2013 at 08:00:07PM +0530, Siddhesh Poyarekar wrote:
> Hi,
> 
> Some math functions have distinct performance characteristics in
> specific domains of inputs, where some inputs return via a fast path
> while other inputs require multiple precision calculations, that too
> at different precision levels.  The way to implement different domains
> was to have a separate source file and benchmark input file, resulting
> in separate programs.
>     
> This clutters up benchtests, so this change allows these domains to be
> consolidated into the same input file.  To do this, the input file
> format is now enhanced to allow comments with a preceding # and
> directives with two # at the begining of a line.  A directive that
> looks like:
> 
> ## name: foo
> 
> tells the benchmark generation script that what follows is a different
> ddomain of inputs.  The value of the 'name' directive (in this case,
> foo) is used in the output.  The two input domains are then executed
> sequentially and their results collated separately.  with the above
> directive, there would be two lines in the result that look like:
>     
>     func(): ....
>     func(foo): ...
>     
> I'll consolidate the documentation for using benchmarks into a README
> along with this information.  The patch applies on top of the earlier
> patch to run for constant time.
> 
> Siddhesh
> 
> 	* benchtests/Makefile (bench): Remove slow benchmarks.
> 	* benchtests/atan-inputs: Add slow benchmark inputs.
> 	* benchtests/bench-modf.c (NUM_VARIANTS): Define.
> 	(BENCH_FUNC): Accept variant offset.
> 	(VARIANT): Define.
> 	* benchtests/bench-skeleton.c (main): Run benchmark for each
> 	variant.
> 	* benchtests/cos-inputs: Add slow benchmark inputs.
> 	* benchtests/exp-inputs: Likewise.
> 	* benchtests/pow-inputs: Likewise.
> 	* benchtests/sin-inputs: Likewise.
> 	* benchtests/slowatan-inputs: Remove.
> 	* benchtests/slowatan.c: Remove.
> 	* benchtests/slowcos-inputs: Remove.
> 	* benchtests/slowcos.c: Remove.
> 	* benchtests/slowexp-inputs: Remove.
> 	* benchtests/slowexp.c: Remove.
> 	* benchtests/slowpow-inputs: Remove.
> 	* benchtests/slowpow.c: Remove.
> 	* benchtests/slowsin-inputs: Remove.
> 	* benchtests/slowsin.c: Remove.
> 	* benchtests/slowtan-inputs: Remove.
> 	* benchtests/slowtan.c: Remove.
> 	* benchtests/tan-inputs: Add slow benchmark inputs.
> 	* scripts/bench.pl: Parse comments and directives.
> 
> 
> diff --git a/benchtests/Makefile b/benchtests/Makefile
> index 9d25d69..19e1be6 100644
> --- a/benchtests/Makefile
> +++ b/benchtests/Makefile
> @@ -39,15 +39,12 @@
>  #   See pow-inputs for an example.
>  
>  subdir := benchtests
> -bench := exp pow rint sin cos tan atan modf \
> -	 slowexp slowpow slowsin slowcos slowtan slowatan
> +bench := exp pow rint sin cos tan atan modf
>  
> -# exp function fast path: sysdeps/ieee754/dbl-64/e_exp.c
>  exp-ARGLIST = double
>  exp-RET = double
>  LDFLAGS-bench-exp = -lm
>  
> -# pow function fast path: sysdeps/ieee754/dbl-64/e_pow.c
>  pow-ARGLIST = double:double
>  pow-RET = double
>  LDFLAGS-bench-pow = -lm
> @@ -56,62 +53,22 @@ rint-ARGLIST = double
>  rint-RET = double
>  LDFLAGS-bench-rint = -lm
>  
> -# exp function slowest path: sysdeps/ieee754/dbl-64/mpexp.c
> -slowexp-ARGLIST = double
> -slowexp-RET = double
> -slowexp-INCLUDE = slowexp.c
> -LDFLAGS-bench-slowexp = -lm
> -
> -# sin function fast path: sysdeps/ieee754/dbl-64/s_sin.c
>  sin-ARGLIST = double
>  sin-RET = double
>  LDFLAGS-bench-sin = -lm
>  
> -# cos function fast path: sysdeps/ieee754/dbl-64/s_sin.c
>  cos-ARGLIST = double
>  cos-RET = double
>  LDFLAGS-bench-cos = -lm
>  
> -# tan function fast path: sysdeps/ieee754/dbl-64/s_tan.c
>  tan-ARGLIST = double
>  tan-RET = double
>  LDFLAGS-bench-tan = -lm
>  
> -# atan function fast path: sysdeps/ieee754/dbl-64/s_atan.c
>  atan-ARGLIST = double
>  atan-RET = double
>  LDFLAGS-bench-atan = -lm
>  
> -# pow function slowest path: sysdeps/ieee754/dbl-64/slowpow.c
> -slowpow-ARGLIST = double:double
> -slowpow-RET = double
> -slowpow-INCLUDE = slowpow.c
> -LDFLAGS-bench-slowpow = -lm
> -
> -# sin function slowest path: sysdeps/ieee754/dbl-64/sincos32.c
> -slowsin-ARGLIST = double
> -slowsin-RET = double
> -slowsin-INCLUDE = slowsin.c
> -LDFLAGS-bench-slowsin = -lm
> -
> -# cos function slowest path: sysdeps/ieee754/dbl-64/sincos32.c
> -slowcos-ARGLIST = double
> -slowcos-RET = double
> -slowcos-INCLUDE = slowcos.c
> -LDFLAGS-bench-slowcos = -lm
> -
> -# tan function slowest path: sysdeps/ieee754/dbl-64/mptan.c
> -slowtan-ARGLIST = double
> -slowtan-RET = double
> -slowtan-INCLUDE = slowtan.c
> -LDFLAGS-bench-slowtan = -lm
> -
> -# atan function slowest path: sysdeps/ieee754/dbl-64/mpatan.c
> -slowatan-ARGLIST = double
> -slowatan-RET = double
> -slowatan-INCLUDE = slowatan.c
> -LDFLAGS-bench-slowatan = -lm
> -
>  
>  
>  # Rules to build and execute the benchmarks.  Do not put any benchmark
> diff --git a/benchtests/atan-inputs b/benchtests/atan-inputs
> index c685db3..4a2cf3a 100644
> --- a/benchtests/atan-inputs
> +++ b/benchtests/atan-inputs
> @@ -1,3 +1,9 @@
>  0x1.000000c5cba86p0
>  0x1.000001883003ap0
>  0x1.00000dfb2b674p0
> +# atan slowest path at 768 bits
> +# Implemented in sysdeps/ieee754/dbl-64/mpatan.c
> +## name: 768bits
> +0x1.000000c5cba87p0
> +0x1.000001883003bp0
> +0x1.00000dfb2b675p0
> diff --git a/benchtests/bench-modf.c b/benchtests/bench-modf.c
> index 90a5255..7fae7dc 100644
> --- a/benchtests/bench-modf.c
> +++ b/benchtests/bench-modf.c
> @@ -17,7 +17,7 @@
>  
>  extern double modf (double, double *);
>  
> -#define CALL_BENCH_FUNC(j, i) modf ( in[j].arg0, &i);
> +#define CALL_BENCH_FUNC(j, i) modf (in[j].arg0, &i);
>  
>  struct args
>  {
> @@ -28,11 +28,17 @@ struct args
>    { -42.42 }
>  };
>  
> -#define NUM_SAMPLES (sizeof (in) / sizeof (struct args))
> +#define NUM_VARIANTS 1
> +#define NUM_SAMPLES(v) (sizeof (in) / sizeof (struct args))
>  
>  static volatile double ret = 0.0;
> -#define BENCH_FUNC(j) ({double iptr; ret =  CALL_BENCH_FUNC (j, iptr);})
> +#define BENCH_FUNC(v, j) \
> +({									      \
> +  double iptr;								      \
> +  ret =  CALL_BENCH_FUNC (j, iptr);					      \
> +})
>  
>  #define FUNCNAME "modf"
> +#define VARIANT(v) FUNCNAME "()"
>  
>  #include "bench-skeleton.c"
> diff --git a/benchtests/bench-skeleton.c b/benchtests/bench-skeleton.c
> index bbd151b..f5dba21 100644
> --- a/benchtests/bench-skeleton.c
> +++ b/benchtests/bench-skeleton.c
> @@ -30,7 +30,6 @@ int
>  main (int argc, char **argv)
>  {
>    unsigned long i, k;
> -  uint64_t total = 0, max = 0, min = 0x7fffffffffffffff;
>    struct timespec start, end, runtime;
>  
>    memset (&runtime, 0, sizeof (runtime));
> @@ -45,53 +44,57 @@ main (int argc, char **argv)
>       but it's better than having nothing at all.  */
>    unsigned long iters = 1000 * start.tv_nsec;
>  
> -  /* Run for approxmately DURATION seconds.  */
> -  clock_gettime (CLOCK_MONOTONIC_RAW, &runtime);
> -  runtime.tv_sec += DURATION;
> -
> -  double d_total_i = 0;
> -  while (1)
> +  for (int v = 0; v < NUM_VARIANTS; v++)
>      {
> -      for (i = 0; i < NUM_SAMPLES; i++)
> -	{
> -	  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &start);
> -	  for (k = 0; k < iters; k++)
> -	    BENCH_FUNC(i);
> -	  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &end);
> +      /* Run for approxmately DURATION seconds.  */
> +      clock_gettime (CLOCK_MONOTONIC_RAW, &runtime);
> +      runtime.tv_sec += DURATION;
>  
> -	  uint64_t cur = (end.tv_nsec - start.tv_nsec
> -			 + ((end.tv_sec - start.tv_sec)
> -			    * (uint64_t) 1000000000));
> +      double d_total_i = 0;
> +      uint64_t total = 0, max = 0, min = 0x7fffffffffffffff;
> +      while (1)
> +	{
> +	  for (i = 0; i < NUM_SAMPLES (v); i++)
> +	    {
> +	      clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &start);
> +	      for (k = 0; k < iters; k++)
> +		BENCH_FUNC (v, i);
> +	      clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &end);
>  
> -	  if (cur > max)
> -	    max = cur;
> +	      uint64_t cur = (end.tv_nsec - start.tv_nsec
> +			      + ((end.tv_sec - start.tv_sec)
> +				 * (uint64_t) 1000000000));
>  
> -	  if (cur < min)
> -	    min = cur;
> +	      if (cur > max)
> +		max = cur;
>  
> -	  total += cur;
> +	      if (cur < min)
> +		min = cur;
>  
> -	  d_total_i += iters;
> -	}
> +	      total += cur;
>  
> -      struct timespec curtime;
> +	      d_total_i += iters;
> +	    }
> +	  struct timespec curtime;
>  
> -      memset (&curtime, 0, sizeof (curtime));
> -      clock_gettime (CLOCK_MONOTONIC_RAW, &curtime);
> -      if (TIMESPEC_AFTER (curtime, runtime))
> -	goto done;
> -    }
> +	  memset (&curtime, 0, sizeof (curtime));
> +	  clock_gettime (CLOCK_MONOTONIC_RAW, &curtime);
> +	  if (TIMESPEC_AFTER (curtime, runtime))
> +	    goto done;
> +	}
>  
> -  double d_total_s;
> -  double d_iters;
> +      double d_total_s;
> +      double d_iters;
>  
> - done:
> -  d_total_s = total * 1e-9;
> -  d_iters = iters;
> +    done:
> +      d_total_s = total * 1e-9;
> +      d_iters = iters;
>  
> -  printf (FUNCNAME ": ITERS:%g: TOTAL:%gs, MAX:%gns, MIN:%gns, %g iter/s\n",
> -	  d_total_i, d_total_s, max / d_iters, min / d_iters,
> -	  d_total_i / d_total_s);
> +      printf ("%s: ITERS:%g: TOTAL:%gs, MAX:%gns, MIN:%gns, %g iter/s\n",
> +	      VARIANT (v),
> +	      d_total_i, d_total_s, max / d_iters, min / d_iters,
> +	      d_total_i / d_total_s);
> +    }
>  
>    return 0;
>  }
> diff --git a/benchtests/cos-inputs b/benchtests/cos-inputs
> index 98f4122..82a4060 100644
> --- a/benchtests/cos-inputs
> +++ b/benchtests/cos-inputs
> @@ -3,3 +3,11 @@
>  0x1.00000162a932ap0
>  0x1.000002d452a11p0
>  0x1.000005bc7d86cp0
> +# cos slow path at 768 bits
> +# Implemented in sysdeps/ieee754/dbl-64/sincos32.c
> +## name: 768bits
> +0x1.000000cf4a2a2p0
> +0x1.0000010b239a9p0
> +0x1.00000162a932bp0
> +0x1.000002d452a10p0
> +0x1.000005bc7d86dp0
> diff --git a/benchtests/exp-inputs b/benchtests/exp-inputs
> index d81cc07..e9d33a3 100644
> --- a/benchtests/exp-inputs
> +++ b/benchtests/exp-inputs
> @@ -1 +1,5 @@
>  42
> +# Slowest path with computation in 768 bit precision.
> +# Implemented in: sysdeps/ieee754/dbl-64/mpexp.c
> +## name: 768bits
> +708.00096423260981737257679924368858
> diff --git a/benchtests/pow-inputs b/benchtests/pow-inputs
> index 2f7cc03..dad6505 100644
> --- a/benchtests/pow-inputs
> +++ b/benchtests/pow-inputs
> @@ -1 +1,5 @@
>  42.0, 42.0
> +# pow slowest path at 768 bits
> +# Implemented in sysdeps/ieee754/dbl-64/slowpow.c
> +## name: 768bits
> +1.0000000000000020, 1.5
> diff --git a/benchtests/sin-inputs b/benchtests/sin-inputs
> index 620cea8..08192d8 100644
> --- a/benchtests/sin-inputs
> +++ b/benchtests/sin-inputs
> @@ -5,3 +5,13 @@
>  4.0
>  4.7
>  5.9
> +# sin slowest path at 768 bits
> +# Implemented in sysdeps/ieee754/dbl-64/sincos32.c
> +## name: 768bits
> +0.93340582292648832662962377071381
> +2.3328432680770916363144351635128
> +3.7439477503636453548097051680088
> +3.9225160069792437411706487182528
> +4.0711651639931289992091478779912
> +4.7858438478542097982426639646292
> +5.9840767662578002727968851104379
> diff --git a/benchtests/slowatan-inputs b/benchtests/slowatan-inputs
> deleted file mode 100644
> index e557a3c..0000000
> --- a/benchtests/slowatan-inputs
> +++ /dev/null
> @@ -1,3 +0,0 @@
> -0x1.000000c5cba87p0
> -0x1.000001883003bp0
> -0x1.00000dfb2b675p0
> diff --git a/benchtests/slowatan.c b/benchtests/slowatan.c
> deleted file mode 100644
> index 9a11d30..0000000
> --- a/benchtests/slowatan.c
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* Define slowatan.
> -   Copyright (C) 2013 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C 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.
> -
> -   The GNU C 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 the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#define slowatan atan
> diff --git a/benchtests/slowcos-inputs b/benchtests/slowcos-inputs
> deleted file mode 100644
> index b7eb235..0000000
> --- a/benchtests/slowcos-inputs
> +++ /dev/null
> @@ -1,5 +0,0 @@
> -0x1.000000cf4a2a2p0
> -0x1.0000010b239a9p0
> -0x1.00000162a932bp0
> -0x1.000002d452a10p0
> -0x1.000005bc7d86dp0
> diff --git a/benchtests/slowcos.c b/benchtests/slowcos.c
> deleted file mode 100644
> index 9f56234..0000000
> --- a/benchtests/slowcos.c
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* Define slowcos.
> -   Copyright (C) 2013 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C 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.
> -
> -   The GNU C 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 the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#define slowcos cos
> diff --git a/benchtests/slowexp-inputs b/benchtests/slowexp-inputs
> deleted file mode 100644
> index a2086ba..0000000
> --- a/benchtests/slowexp-inputs
> +++ /dev/null
> @@ -1 +0,0 @@
> -708.00096423260981737257679924368858
> diff --git a/benchtests/slowexp.c b/benchtests/slowexp.c
> deleted file mode 100644
> index 92ac5e9..0000000
> --- a/benchtests/slowexp.c
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* Define slowexp.
> -   Copyright (C) 2013 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C 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.
> -
> -   The GNU C 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 the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#define slowexp exp
> diff --git a/benchtests/slowpow-inputs b/benchtests/slowpow-inputs
> deleted file mode 100644
> index dbb1270..0000000
> --- a/benchtests/slowpow-inputs
> +++ /dev/null
> @@ -1 +0,0 @@
> -1.0000000000000020, 1.5
> diff --git a/benchtests/slowpow.c b/benchtests/slowpow.c
> deleted file mode 100644
> index 08f436d..0000000
> --- a/benchtests/slowpow.c
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* Define slowpow.
> -   Copyright (C) 2013 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C 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.
> -
> -   The GNU C 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 the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#define slowpow pow
> diff --git a/benchtests/slowsin-inputs b/benchtests/slowsin-inputs
> deleted file mode 100644
> index 39daf80..0000000
> --- a/benchtests/slowsin-inputs
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -0.93340582292648832662962377071381
> -2.3328432680770916363144351635128
> -3.7439477503636453548097051680088
> -3.9225160069792437411706487182528
> -4.0711651639931289992091478779912
> -4.7858438478542097982426639646292
> -5.9840767662578002727968851104379
> diff --git a/benchtests/slowsin.c b/benchtests/slowsin.c
> deleted file mode 100644
> index b6809bd..0000000
> --- a/benchtests/slowsin.c
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* Define slowsin.
> -   Copyright (C) 2013 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C 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.
> -
> -   The GNU C 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 the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#define slowsin sin
> diff --git a/benchtests/slowtan-inputs b/benchtests/slowtan-inputs
> deleted file mode 100644
> index 74a7eab..0000000
> --- a/benchtests/slowtan-inputs
> +++ /dev/null
> @@ -1 +0,0 @@
> -0x1.dffffffffff1fp-22
> diff --git a/benchtests/slowtan.c b/benchtests/slowtan.c
> deleted file mode 100644
> index 583f16f..0000000
> --- a/benchtests/slowtan.c
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -/* Define slowtan.
> -   Copyright (C) 2013 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C 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.
> -
> -   The GNU C 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 the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#define slowtan tan
> diff --git a/benchtests/tan-inputs b/benchtests/tan-inputs
> index 4369d75..629414f 100644
> --- a/benchtests/tan-inputs
> +++ b/benchtests/tan-inputs
> @@ -1 +1,5 @@
>  0x1.dffffffffff1ep-22
> +# tan slowest path at 768 bits
> +# Implemented in sysdeps/ieee754/dbl-64/mptan.c
> +## name: 768bits
> +0x1.dffffffffff1fp-22
> diff --git a/scripts/bench.pl b/scripts/bench.pl
> index 5856cfa..dcc5ead 100755
> --- a/scripts/bench.pl
> +++ b/scripts/bench.pl
> @@ -42,15 +42,28 @@ if (@ARGV == 3) {
>  
>  my $decl = "extern $ret $func (";
>  
> +# Function has no arguments.
>  if (@args == 0 || $args[0] eq "void") {
>    print "$decl void);\n";
> -  print "#define CALL_BENCH_FUNC(j) $func();\n";
> -  print "#define NUM_SAMPLES (1)\n";
> +  print "#define CALL_BENCH_FUNC(i,j) $func();\n";
> +  print "#define NUM_VARIANTS (1)\n";
> +  print "#define NUM_SAMPLES(v) (1)\n";
> +  print "#define VARIANT(v) FUNCNAME \"()\"\n"
>  }
> +# The function has arguments, so parse them and populate the inputs.
>  else {
>    my $num = 0;
> -  my $bench_func = "#define CALL_BENCH_FUNC(j) $func (";
> -  my $struct = "struct args {";
> +  my $bench_func = "#define CALL_BENCH_FUNC(v, i) $func (";
> +
> +  my $struct =
> +    "struct _variants
> +    {
> +      const char *name;
> +      int count;
> +      struct args *in;
> +    };\n";
> +
> +  my $arg_struct = "struct args {";
>  
>    foreach $arg (@args) {
>      if ($num > 0) {
> @@ -58,24 +71,87 @@ else {
>        $decl = "$decl,";
>      }
>  
> -    $struct = "$struct $arg arg$num;";
> -    $bench_func = "$bench_func in[j].arg$num";
> +    $arg_struct = "$arg_struct $arg arg$num;";
> +    $bench_func = "$bench_func variants[v].in[i].arg$num";
>      $decl = "$decl $arg";
>      $num = $num + 1;
>    }
>  
> -  print "$decl);\n";
> -  print "$bench_func);\n";
> -  print "$struct } in[] = {";
> +  $arg_struct = $arg_struct . "};\n";
> +  $decl = $decl . ");\n";
> +  $bench_func = $bench_func . ");\n";
> +
> +  # We create a hash of inputs for each variant of the test.
> +  my $variant = "";
> +  my @curvals;
> +  my %vals;
>  
>    open INPUTS, "<$func-inputs" or die $!;
>  
> -  while (<INPUTS>) {
> +  LINE:while (<INPUTS>) {
>      chomp;
> -    print "{$_},\n";
> +
> +    # New variant.
> +    if (/^## (\w+): (\w+)/) {
> +      #We only identify Name for now.
> +      if ($1 ne "name") {
> +        next LINE;
> +      }
> +
> +      # Save values in the last variant.
> +      my @copy = @curvals;
> +      $vals{$variant} = \@copy;
> +
> +      # Prepare for the next.
> +      $variant=$2;
> +      undef @curvals;
> +      next LINE;
> +    }
> +
> +    # Skip over comments.
> +    if (/^#/) {
> +      next LINE;
> +    }
> +    push (@curvals, $_);
>    }
> -  print "};\n";
> -  print "#define NUM_SAMPLES (sizeof (in) / sizeof (struct args))\n"
> +
> +  $vals{$variant} = \@curvals;
> +
> +  # Print the definitions and macros.
> +  print $decl;
> +  print $bench_func;
> +  print $arg_struct;
> +  print $struct;
> +
> +  my $c = 0;
> +  my $key;
> +
> +  # Print the input arrays.
> +  foreach $key (keys %vals) {
> +    my @arr = @{$vals{$key}};
> +
> +    print "struct args in" . $c . "[" . @arr . "] = {\n";
> +    foreach (@arr) {
> +      print "{$_},\n";
> +    }
> +    print "};\n\n";
> +    $c += 1;
> +  }
> +
> +  # The variants.  Each variant then points to the appropriate input array we
> +  # defined above.
> +  print "struct _variants variants[" . (keys %vals) . "] = {\n";
> +  $c = 0;
> +  foreach $key (keys %vals) {
> +    print "{\"$func($key)\", " . @{$vals{$key}} . ", in$c},\n";
> +    $c += 1;
> +  }
> +  print "};\n\n";
> +
> +  # Finally, print the last set of macros.
> +  print "#define NUM_VARIANTS $c\n";
> +  print "#define NUM_SAMPLES(i) (variants[i].count)\n";
> +  print "#define VARIANT(i) (variants[i].name)\n";
>  }
>  
>  # In some cases not storing a return value seems to result in the function call
> @@ -85,7 +161,8 @@ if ($ret ne "void") {
>    $getret = "ret = ";
>  }
>  
> -print "#define BENCH_FUNC(j) ({$getret CALL_BENCH_FUNC (j);})\n";
> +# And we're done.
> +print "#define BENCH_FUNC(i, j) ({$getret CALL_BENCH_FUNC (i, j);})\n";
>  
>  print "#define FUNCNAME \"$func\"\n";
>  print "#include \"bench-skeleton.c\"\n";


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]