LCOV - code coverage report
Current view: top level - ecm - bench_mulredc.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 418 459 91.1 %
Date: 2022-03-21 11:19:20 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "config.h"
       2             : #include <stdio.h>
       3             : #include <stdlib.h>
       4             : #include <limits.h> /* for LONG_MAX */
       5             : #include <assert.h>
       6             : #include <time.h>
       7             : #include <string.h>
       8             : 
       9             : #if TIME_WITH_SYS_TIME
      10             : # include <sys/time.h>
      11             : # include <time.h>
      12             : #else
      13             : # if HAVE_SYS_TIME_H
      14             : #  include <sys/time.h>
      15             : # else
      16             : #  include <time.h>
      17             : # endif
      18             : #endif
      19             : 
      20             : #define LOOPCOUNT 10000000UL
      21             : #define MAXSIZE 20
      22             : 
      23             : int tune_mul[MAXSIZE+1], tune_sqr[MAXSIZE+1], redc_n_ok[MAXSIZE+1];
      24             : int verbose = 0;
      25             : 
      26             : #include <gmp.h>
      27             : #ifdef USE_ASM_REDC
      28             : #include "mulredc.h"
      29             : #endif
      30             : #include "mpmod.h"
      31             : #include "ecm-gmp.h"
      32             : 
      33             : #ifdef HAVE___GMPN_REDC_N
      34             : #ifndef __gmpn_redc_N
      35             : void __gmpn_redc_n (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
      36             : #endif
      37             : #endif
      38             : 
      39             : /* cputime () gives the elapsed time in milliseconds */
      40             : 
      41             : #if defined (_WIN32)
      42             : /* First case - GetProcessTimes () is the only known way of getting process
      43             :  * time (as opposed to calendar time) under mingw32 */
      44             : 
      45             : #include <windows.h>
      46             : 
      47             : long
      48             : cputime ()
      49             : {
      50             :   FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTime;
      51             :   ULARGE_INTEGER n;
      52             : 
      53             :   HANDLE hProcess = GetCurrentProcess();
      54             :   
      55             :   GetProcessTimes (hProcess, &lpCreationTime, &lpExitTime, &lpKernelTime,
      56             :       &lpUserTime);
      57             : 
      58             :   /* copy FILETIME to a ULARGE_INTEGER as recommended by MSDN docs */
      59             :   n.u.LowPart = lpUserTime.dwLowDateTime;
      60             :   n.u.HighPart = lpUserTime.dwHighDateTime;
      61             : 
      62             :   /* lpUserTime is in units of 100 ns. Return time in milliseconds */
      63             :   return (long) (n.QuadPart / 10000);
      64             : }
      65             : 
      66             : #elif defined (HAVE_GETRUSAGE)
      67             : /* Next case: getrusage () has higher resolution than clock () and so is
      68             :    preferred. */
      69             : 
      70             : #ifdef HAVE_SYS_TYPES_H
      71             : # include <sys/types.h>
      72             : #endif
      73             : #ifdef HAVE_SYS_RESOURCE_H
      74             : # include <sys/resource.h>
      75             : #endif
      76             : 
      77             : long
      78         937 : cputime ()
      79             : {
      80             :   struct rusage rus;
      81             : 
      82         937 :   getrusage (RUSAGE_SELF, &rus);
      83             :   /* This overflows a 32 bit signed int after 2147483s = 24.85 days */
      84         937 :   return rus.ru_utime.tv_sec * 1000L + rus.ru_utime.tv_usec / 1000L;
      85             : }
      86             : 
      87             : #else
      88             : /* Resort to clock (), which on some systems may return calendar time. */
      89             : 
      90             : long
      91             : cputime ()
      92             : {
      93             :   /* Return time in milliseconds */
      94             :   return (long) (clock () * (1000. / (double) CLOCKS_PER_SEC));
      95             : }
      96             : 
      97             : #endif /* defining cputime () */
      98             : 
      99          20 : void bench(mp_size_t N)
     100             : {
     101             :   mp_limb_t *x, *y, *z, *zref, *m, *invm, *tmp;
     102             :   unsigned long i;
     103             :   unsigned long iter;
     104             :   long tmul, tsqr, tredc_1, t_mulredc_1, t_sqrredc_1;
     105          20 :   long tmul_best = LONG_MAX, tsqr_best = LONG_MAX, tredc_best = LONG_MAX;
     106             :   mpz_t M, B;
     107             : #ifdef USE_ASM_REDC
     108             :   long t2;
     109             : #endif
     110             : #ifdef HAVE_NATIVE_MULREDC1_N
     111          20 :   long t3 = 0;
     112             : #endif
     113             : #ifdef HAVE___GMPN_REDC_2
     114             :   long tredc_2, t_mulredc_2, t_sqrredc_2;
     115             : #endif
     116             : #ifdef HAVE___GMPN_REDC_N
     117          20 :   long tredc_n = LONG_MAX, t_mulredc_n, t_sqrredc_n;
     118             : #endif
     119             :   
     120          20 :   x = (mp_limb_t *) malloc(N*sizeof(mp_limb_t));
     121          20 :   y = (mp_limb_t *) malloc(N*sizeof(mp_limb_t));
     122          20 :   z = (mp_limb_t *) malloc((2*N)*sizeof(mp_limb_t));
     123          20 :   zref = (mp_limb_t *) malloc((2*N)*sizeof(mp_limb_t));
     124          20 :   m = (mp_limb_t *) malloc(N*sizeof(mp_limb_t));
     125          20 :   tmp = (mp_limb_t *) malloc((2*N+2)*sizeof(mp_limb_t));
     126          20 :   invm = (mp_limb_t *) malloc(N*sizeof(mp_limb_t));
     127             :  
     128          20 :   mpn_random(m, N);
     129          20 :   m[0] |= 1UL;
     130          20 :   if (m[N-1] == 0) 
     131           0 :     m[N-1] = 1UL;
     132             : 
     133          20 :   mpz_init (M);
     134          20 :   mpz_init (B);
     135          20 :   mpz_set_ui (M, m[1]);
     136          20 :   mpz_mul_2exp (M, M, GMP_NUMB_BITS);
     137          20 :   mpz_add_ui (M, M, m[0]);
     138          20 :   mpz_set_ui (B, 1);
     139          20 :   mpz_mul_2exp (B, B, 2 * GMP_NUMB_BITS);
     140          20 :   mpz_invert (M, M, B);
     141          20 :   mpz_sub (M, B, M);
     142             : 
     143         230 :   for (i = 0; i < (unsigned) N; i++)
     144         210 :     invm[i] = mpz_getlimbn(M, i);
     145             : 
     146          20 :   tmp[N] = mpn_mul_1 (tmp, m, N, invm[0]); /* {tmp,N+1} should be = -1 mod B */
     147          20 :   mpn_add_1 (tmp, tmp, N + 1, 1); /* now = 0 mod B */
     148             : 
     149          20 :   mpz_clear (M);
     150          20 :   mpz_clear (B);
     151             : 
     152          20 :   mpn_random(x, N);
     153          20 :   mpn_random(y, N);
     154             : 
     155             :   /* we set 'iter' to get about 100ms for each test */
     156          20 :   tmul = cputime();
     157          20 :   i = 0;
     158          20 :   iter = 1;
     159             :   do
     160             :     {
     161         417 :       iter = 2 * iter;
     162    76546465 :       for (; i < iter; i++)
     163    76546048 :         mpn_mul_n (tmp, x, y, N);
     164             :     }
     165         417 :   while (cputime() - tmul < 100);
     166          20 :   iter = (long) (((double) iter * 100.0) / (double) (cputime() - tmul));
     167             : 
     168          20 :   tmul = cputime();
     169    54199432 :   for (i = 0; i < iter; ++i)
     170    54199412 :     mpn_mul_n(tmp, x, y, N);
     171          20 :   tmul = cputime()-tmul;
     172             : 
     173          20 :   tsqr = cputime();
     174    54199432 :   for (i = 0; i < iter; ++i)
     175    54199412 :     mpn_sqr (tmp, x, N);
     176          20 :   tsqr = cputime()-tsqr;
     177             : 
     178             :   /* compute reference redc result */
     179          20 :   mpn_mul_n (zref, x, y, N);
     180       13460 :   for (i = 0; i < (unsigned long) N * GMP_NUMB_BITS; i++)
     181             :     {
     182       13440 :       mp_limb_t cy = 0;
     183       13440 :       if (zref[0] & 1)
     184        6695 :         cy = mpn_add (zref, zref, 2*N, m, N);
     185       13440 :       mpn_rshift (zref, zref, 2*N, 1);
     186       13440 :       zref[2*N-1] |= cy << (GMP_NUMB_BITS - 1);
     187             :     }
     188             : 
     189             : #ifdef HAVE___GMPN_REDC_1
     190          20 :   mpn_mul_n(tmp, x, y, N);
     191          20 :   REDC1(z, tmp, m, N, invm[0]);
     192             :   ASSERT (mpn_cmp (z, zref, N) == 0);
     193          20 :   tredc_1 = cputime();
     194    54199432 :   for (i = 0; i < iter; ++i)
     195    54199412 :     REDC1(z, tmp, m, N, invm[0]);
     196          20 :   tredc_1 = cputime()-tredc_1;
     197          20 :   if (tredc_1 < tredc_best)
     198          20 :     tredc_best = tredc_1;
     199             : #endif
     200             : 
     201             : #ifdef HAVE___GMPN_REDC_2
     202          20 :   mpn_mul_n(tmp, x, y, N);
     203          20 :   REDC2 (z, tmp, m, N, invm);
     204             :   ASSERT (mpn_cmp (z, zref, N) == 0);
     205          20 :   tredc_2 = cputime();
     206    54199432 :   for (i = 0; i < iter; ++i)
     207    54199412 :     REDC2 (z, tmp, m, N, invm);
     208          20 :   tredc_2 = cputime() - tredc_2;
     209          20 :   if (tredc_2 < tredc_best)
     210           0 :     tredc_best = tredc_2;
     211             : #endif
     212             : 
     213             : /* GMP uses the opposite convention for the precomputed inverse in redc_n
     214             :    wrt redc_1 or redc_2, which gives wrong results so far. */
     215             : #ifdef HAVE___GMPN_REDC_N
     216          20 :   mpn_mul_n(tmp, x, y, N);
     217          20 :   __gmpn_redc_n (z, tmp, m, N, invm);
     218          20 :   if (mpn_cmp (z, zref, N) != 0)
     219          20 :     redc_n_ok[N] = 0;
     220             :   else
     221             :     {
     222           0 :       redc_n_ok[N] = 1;
     223           0 :       tredc_n = cputime();
     224           0 :       for (i = 0; i < iter; ++i)
     225           0 :         __gmpn_redc_n (z, tmp, m, N, invm);
     226           0 :       tredc_n = cputime()-tredc_n;
     227           0 :       if (tredc_n < tredc_best)
     228           0 :         tredc_best = tredc_n;
     229             :     }
     230             : #endif
     231             : 
     232             : #ifdef USE_ASM_REDC
     233             :   /* Mixed mul and redc */
     234          20 :   t2 = cputime();
     235          20 :   switch (N) {
     236           1 :    case 1:
     237    13751817 :     for (i=0; i < iter; ++i) {
     238    13751816 :       mulredc1(z, x[0], y[0], m[0], invm[0]);
     239    13751816 :       x[0] += tmp[0];
     240             :     }
     241           1 :     break;
     242           1 :    case 2:
     243    10292771 :     for (i=0; i < iter; ++i) {
     244    10292770 :       mulredc2(z, x, y, m, invm[0]);
     245    10292770 :       x[0] += tmp[0];
     246             :     }
     247           1 :     break;
     248           1 :    case 3:
     249     7231559 :     for (i=0; i < iter; ++i) {
     250     7231558 :       mulredc3(z, x, y, m, invm[0]);
     251     7231558 :       x[0] += tmp[0];
     252             :     }
     253           1 :     break;
     254           1 :    case 4:
     255     5343063 :     for (i=0; i < iter; ++i) {
     256     5343062 :       mulredc4(z, x, y, m, invm[0]);
     257     5343062 :       x[0] += tmp[0];
     258             :     }
     259           1 :     break;
     260           1 :    case 5:
     261     3679215 :     for (i=0; i < iter; ++i) {
     262     3679214 :       mulredc5(z, x, y, m, invm[0]);
     263     3679214 :       x[0] += tmp[0];
     264             :     }
     265           1 :     break;
     266           1 :    case 6:
     267     2796203 :     for (i=0; i < iter; ++i) {
     268     2796202 :       mulredc6(z, x, y, m, invm[0]);
     269     2796202 :       x[0] += tmp[0];
     270             :     }
     271           1 :     break;
     272           1 :    case 7:
     273     2107691 :     for (i=0; i < iter; ++i) {
     274     2107690 :       mulredc7(z, x, y, m, invm[0]);
     275     2107690 :       x[0] += tmp[0];
     276             :     }
     277           1 :     break;
     278           1 :    case 8:
     279     1588752 :     for (i=0; i < iter; ++i) {
     280     1588751 :       mulredc8(z, x, y, m, invm[0]);
     281     1588751 :       x[0] += tmp[0];
     282             :     }
     283           1 :     break;
     284           1 :    case 9:
     285     1335766 :     for (i=0; i < iter; ++i) {
     286     1335765 :       mulredc9(z, x, y, m, invm[0]);
     287     1335765 :       x[0] += tmp[0];
     288             :     }
     289           1 :     break;
     290           1 :    case 10:
     291     1081007 :     for (i=0; i < iter; ++i) {
     292     1081006 :       mulredc10(z, x, y, m, invm[0]);
     293     1081006 :       x[0] += tmp[0];
     294             :     }
     295           1 :     break;
     296           1 :    case 11:
     297      881157 :     for (i=0; i < iter; ++i) {
     298      881156 :       mulredc11(z, x, y, m, invm[0]);
     299      881156 :       x[0] += tmp[0];
     300             :     }
     301           1 :     break;
     302           1 :    case 12:
     303      748983 :     for (i=0; i < iter; ++i) {
     304      748982 :       mulredc12(z, x, y, m, invm[0]);
     305      748982 :       x[0] += tmp[0];
     306             :     }
     307           1 :     break;
     308           1 :    case 13:
     309      639376 :     for (i=0; i < iter; ++i) {
     310      639375 :       mulredc13(z, x, y, m, invm[0]);
     311      639375 :       x[0] += tmp[0];
     312             :     }
     313           1 :     break;
     314           1 :    case 14:
     315      560736 :     for (i=0; i < iter; ++i) {
     316      560735 :       mulredc14(z, x, y, m, invm[0]);
     317      560735 :       x[0] += tmp[0];
     318             :     }
     319           1 :     break;
     320           1 :    case 15:
     321      476626 :     for (i=0; i < iter; ++i) {
     322      476625 :       mulredc15(z, x, y, m, invm[0]);
     323      476625 :       x[0] += tmp[0];
     324             :     }
     325           1 :     break;
     326           1 :    case 16:
     327      419431 :     for (i=0; i < iter; ++i) {
     328      419430 :       mulredc16(z, x, y, m, invm[0]);
     329      419430 :       x[0] += tmp[0];
     330             :     }
     331           1 :     break;
     332           1 :    case 17:
     333      371836 :     for (i=0; i < iter; ++i) {
     334      371835 :       mulredc17(z, x, y, m, invm[0]);
     335      371835 :       x[0] += tmp[0];
     336             :     }
     337           1 :     break;
     338           1 :    case 18:
     339      329741 :     for (i=0; i < iter; ++i) {
     340      329740 :       mulredc18(z, x, y, m, invm[0]);
     341      329740 :       x[0] += tmp[0];
     342             :     }
     343           1 :     break;
     344           1 :    case 19:
     345      296208 :     for (i=0; i < iter; ++i) {
     346      296207 :       mulredc19(z, x, y, m, invm[0]);
     347      296207 :       x[0] += tmp[0];
     348             :     }
     349           1 :     break;
     350           1 :    case 20:
     351      267494 :     for (i=0; i < iter; ++i) {
     352      267493 :       mulredc20(z, x, y, m, invm[0]);
     353      267493 :       x[0] += tmp[0];
     354             :     }
     355           1 :     break;
     356           0 :    default:
     357           0 :     for (i=0; i < iter; ++i) {
     358           0 :       mulredc20(z, x, y, m,  invm[0]);
     359           0 :       x[0] += tmp[0];
     360             :     }
     361             :   }
     362          20 :   t2 = cputime()-t2;
     363          20 :   if (t2 < tmul_best)
     364             :     {
     365          20 :       tmul_best = t2;
     366          20 :       tune_mul[N] = MPMOD_MULREDC;
     367             :     }
     368          20 :   if (t2 < tsqr_best)
     369             :     {
     370          20 :       tsqr_best = t2;
     371          20 :       tune_sqr[N] = MPMOD_MULREDC;
     372             :     }
     373             : #endif
     374             :   
     375             :   /* Mul followed by mpn_redc_1 */
     376             : #ifdef HAVE___GMPN_REDC_1
     377          20 :   t_mulredc_1 = cputime();
     378    54199432 :   for (i = 0; i < iter; ++i) {
     379    54199412 :     mpn_mul_n(tmp, x, y, N);
     380    54199412 :     __gmpn_redc_1 (z, tmp, m, N, invm[0]);
     381    54199412 :     x[0] += tmp[0];
     382             :   }
     383          20 :   t_mulredc_1 = cputime()-t_mulredc_1;
     384          20 :   if (t_mulredc_1 < tmul_best)
     385             :     {
     386          13 :       tune_mul[N] = MPMOD_MUL_REDC1;
     387          13 :       tmul_best = t_mulredc_1;
     388             :     }
     389             : #endif
     390             :   
     391             :   /* Mul followed by mpn_redc_2 */
     392             : #ifdef HAVE___GMPN_REDC_2
     393          20 :   t_mulredc_2 = cputime();
     394    54199432 :   for (i = 0; i < iter; ++i) {
     395    54199412 :     mpn_mul_n(tmp, x, y, N);
     396    54199412 :     __gmpn_redc_2 (z, tmp, m, N, invm);
     397    54199412 :     x[0] += tmp[0];
     398             :   }
     399          20 :   t_mulredc_2 = cputime()-t_mulredc_2;
     400          20 :   if (t_mulredc_2 < tmul_best)
     401             :     {
     402           0 :       tune_mul[N] = MPMOD_MUL_REDC2;
     403           0 :       tmul_best = t_mulredc_2;
     404             :     }
     405             : #endif
     406             :   
     407             :   /* Mul followed by mpn_redc_n */
     408             : #ifdef HAVE___GMPN_REDC_N
     409          20 :   t_mulredc_n = cputime();
     410    54199432 :   for (i = 0; i < iter; ++i)
     411             :     {
     412    54199412 :       mpn_mul_n (tmp, x, y, N);
     413    54199412 :       __gmpn_redc_n (z, tmp, m, N, invm);
     414             :     }
     415          20 :   t_mulredc_n = cputime()-t_mulredc_n;
     416          20 :   if (redc_n_ok[N] && t_mulredc_n < tmul_best)
     417             :     {
     418           0 :       tune_mul[N] = MPMOD_MUL_REDCN;
     419           0 :       tmul_best = t_mulredc_n;
     420             :     }
     421             : #endif
     422             :   
     423             :   /* Sqr followed by mpn_redc_1 */
     424             : #ifdef HAVE___GMPN_REDC_1
     425          20 :   t_sqrredc_1 = cputime();
     426    54199432 :   for (i = 0; i < iter; ++i) {
     427    54199412 :     mpn_sqr(tmp, x, N);
     428    54199412 :     __gmpn_redc_1 (z, tmp, m, N, invm[0]);
     429    54199412 :     x[0] += tmp[0];
     430             :   }
     431          20 :   t_sqrredc_1 = cputime()-t_sqrredc_1;
     432          20 :   if (t_sqrredc_1 < tsqr_best)
     433             :     {
     434          16 :       tune_sqr[N] = MPMOD_MUL_REDC1;
     435          16 :       tsqr_best = t_sqrredc_1;
     436             :     }
     437             : #endif
     438             :   
     439             :   /* Sqr followed by mpn_redc_2 */
     440             : #ifdef HAVE___GMPN_REDC_2
     441          20 :   t_sqrredc_2 = cputime();
     442    54199432 :   for (i = 0; i < iter; ++i) {
     443    54199412 :     mpn_sqr(tmp, x, N);
     444    54199412 :     __gmpn_redc_2 (z, tmp, m, N, invm);
     445    54199412 :     x[0] += tmp[0];
     446             :   }
     447          20 :   t_sqrredc_2 = cputime()-t_sqrredc_2;
     448          20 :   if (t_sqrredc_2 < tsqr_best)
     449             :     {
     450           0 :       tune_sqr[N] = MPMOD_MUL_REDC2;
     451           0 :       tsqr_best = t_sqrredc_2;
     452             :     }
     453             : #endif
     454             :   
     455             :   /* Sqr followed by mpn_redc_n */
     456             : #ifdef HAVE___GMPN_REDC_N
     457          20 :   t_sqrredc_n = cputime();
     458    54199432 :   for (i = 0; i < iter; ++i)
     459             :     {
     460    54199412 :       mpn_sqr (tmp, x, N);
     461    54199412 :       __gmpn_redc_n (z, tmp, m, N, invm);
     462             :     }
     463          20 :   t_sqrredc_n = cputime()-t_sqrredc_n;
     464          20 :   if (redc_n_ok[N] && t_sqrredc_n < tsqr_best)
     465             :     {
     466           0 :       tune_sqr[N] = MPMOD_MUL_REDCN;
     467           0 :       tsqr_best = t_sqrredc_n;
     468             :     }
     469             : #endif
     470             :   
     471             : #ifdef HAVE_NATIVE_MULREDC1_N
     472             :   /* mulredc1 */
     473          20 :   t3 = cputime();
     474          20 :   switch (N) {
     475           1 :    case 1:
     476    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     477    10000000 :       mulredc1(z, x[0], y[0], m[0], invm[0]);
     478    10000000 :       x[0] += tmp[0];
     479             :     }
     480           1 :     break;
     481           1 :    case 2:
     482    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     483    10000000 :       mulredc1_2(z, x[0], y, m, invm[0]);
     484    10000000 :       x[0] += tmp[0];
     485             :     }
     486           1 :     break;
     487           1 :    case 3:
     488    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     489    10000000 :       mulredc1_3(z, x[0], y, m, invm[0]);
     490    10000000 :       x[0] += tmp[0];
     491             :     }
     492           1 :     break;
     493           1 :    case 4:
     494    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     495    10000000 :       mulredc1_4(z, x[0], y, m, invm[0]);
     496    10000000 :       x[0] += tmp[0];
     497             :     }
     498           1 :     break;
     499           1 :    case 5:
     500    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     501    10000000 :       mulredc1_5(z, x[0], y, m, invm[0]);
     502    10000000 :       x[0] += tmp[0];
     503             :     }
     504           1 :     break;
     505           1 :    case 6:
     506    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     507    10000000 :       mulredc1_6(z, x[0], y, m, invm[0]);
     508    10000000 :       x[0] += tmp[0];
     509             :     }
     510           1 :     break;
     511           1 :    case 7:
     512    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     513    10000000 :       mulredc1_7(z, x[0], y, m, invm[0]);
     514    10000000 :       x[0] += tmp[0];
     515             :     }
     516           1 :     break;
     517           1 :    case 8:
     518    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     519    10000000 :       mulredc1_8(z, x[0], y, m, invm[0]);
     520    10000000 :       x[0] += tmp[0];
     521             :     }
     522           1 :     break;
     523           1 :    case 9:
     524    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     525    10000000 :       mulredc1_9(z, x[0], y, m, invm[0]);
     526    10000000 :       x[0] += tmp[0];
     527             :     }
     528           1 :     break;
     529           1 :    case 10:
     530    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     531    10000000 :       mulredc1_10(z, x[0], y, m, invm[0]);
     532    10000000 :       x[0] += tmp[0];
     533             :     }
     534           1 :     break;
     535           1 :    case 11:
     536    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     537    10000000 :       mulredc1_11(z, x[0], y, m, invm[0]);
     538    10000000 :       x[0] += tmp[0];
     539             :     }
     540           1 :     break;
     541           1 :    case 12:
     542    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     543    10000000 :       mulredc1_12(z, x[0], y, m, invm[0]);
     544    10000000 :       x[0] += tmp[0];
     545             :     }
     546           1 :     break;
     547           1 :    case 13:
     548    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     549    10000000 :       mulredc1_13(z, x[0], y, m, invm[0]);
     550    10000000 :       x[0] += tmp[0];
     551             :     }
     552           1 :     break;
     553           1 :    case 14:
     554    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     555    10000000 :       mulredc1_14(z, x[0], y, m, invm[0]);
     556    10000000 :       x[0] += tmp[0];
     557             :     }
     558           1 :     break;
     559           1 :    case 15:
     560    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     561    10000000 :       mulredc1_15(z, x[0], y, m, invm[0]);
     562    10000000 :       x[0] += tmp[0];
     563             :     }
     564           1 :     break;
     565           1 :    case 16:
     566    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     567    10000000 :       mulredc1_16(z, x[0], y, m, invm[0]);
     568    10000000 :       x[0] += tmp[0];
     569             :     }
     570           1 :     break;
     571           1 :    case 17:
     572    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     573    10000000 :       mulredc1_17(z, x[0], y, m, invm[0]);
     574    10000000 :       x[0] += tmp[0];
     575             :     }
     576           1 :     break;
     577           1 :    case 18:
     578    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     579    10000000 :       mulredc1_18(z, x[0], y, m, invm[0]);
     580    10000000 :       x[0] += tmp[0];
     581             :     }
     582           1 :     break;
     583           1 :    case 19:
     584    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     585    10000000 :       mulredc1_19(z, x[0], y, m, invm[0]);
     586    10000000 :       x[0] += tmp[0];
     587             :     }
     588           1 :     break;
     589           1 :    case 20:
     590    10000001 :     for (i=0; i<LOOPCOUNT; ++i) {
     591    10000000 :       mulredc1_20(z, x[0], y, m, invm[0]);
     592    10000000 :       x[0] += tmp[0];
     593             :     }
     594           1 :     break;
     595          20 :    default: ;
     596             :   }
     597          20 :   t3 = cputime() - t3;
     598             : #endif /* ifdef HAVE_NATIVE_MULREDC1_N */
     599             : 
     600          20 :   if (verbose)
     601             :     {
     602          20 :       fprintf (stderr, "******************\n");
     603          20 :       fprintf (stderr, "Time in microseconds per call, size=%lu (iter=%lu):\n",
     604             :                N, iter);
     605             : 
     606             :       /* basic operations */
     607          20 :       fprintf (stderr, "mpn_mul_n  = %.3f\n",
     608          20 :                (double) tmul * 1e3 / (double) iter);
     609          20 :       fprintf (stderr, "mpn_sqr    = %.3f\n",
     610          20 :                (double) tsqr * 1e3 / (double) iter);
     611             : #ifdef HAVE___GMPN_REDC_1
     612          20 :       fprintf (stderr, "mpn_redc_1 = %.3f",
     613          20 :                (double) tredc_1 * 1e3 / (double) iter);
     614          20 :       if (tredc_1 == tredc_best)
     615          20 :         fprintf (stderr, " *");
     616          20 :       fprintf (stderr, "\n");
     617             : #endif
     618             : #ifdef HAVE___GMPN_REDC_2
     619          20 :       fprintf (stderr, "mpn_redc_2 = %.3f",
     620          20 :                (double) tredc_2 * 1e3 / (double) iter);
     621          20 :       if (tredc_2 == tredc_best)
     622           0 :         fprintf (stderr, " *");
     623          20 :       fprintf (stderr, "\n");
     624             : #endif
     625             : #ifdef HAVE___GMPN_REDC_N
     626          20 :       if (redc_n_ok[N])
     627             :         {
     628           0 :           fprintf (stderr, "mpn_redc_n = %.3f",
     629           0 :                    (double) tredc_n * 1e3 / (double) iter);
     630           0 :           if (tredc_n == tredc_best)
     631           0 :             fprintf (stderr, " *");
     632           0 :           fprintf (stderr, "\n");
     633             :         }
     634             :   else
     635          20 :     fprintf (stderr, "mpn_redc_n = disabled\n");
     636             : #endif
     637             : 
     638          20 :       fprintf (stderr, "\n");
     639             : 
     640             :   /* modular multiplication */
     641             : #ifdef USE_ASM_REDC
     642          20 :       fprintf (stderr, "mulredc    = %.3f",
     643          20 :                (double) t2 * 1e3 / (double) iter);
     644          20 :       if (tmul_best == t2)
     645           7 :         fprintf (stderr, " *");
     646          20 :       fprintf (stderr, "\n");
     647             : #endif
     648             : #ifdef HAVE___GMPN_REDC_1
     649          20 :       fprintf (stderr, "mul+redc_1 = %.3f",
     650          20 :                (double) t_mulredc_1 * 1e3 / (double) iter);
     651          20 :       if (tmul_best == t_mulredc_1)
     652          13 :         fprintf (stderr, " *");
     653          20 :       fprintf (stderr, "\n");
     654             : #endif
     655             : #ifdef HAVE___GMPN_REDC_2
     656          20 :       fprintf (stderr, "mul+redc_2 = %.3f",
     657          20 :                (double) t_mulredc_2 * 1e3 / (double) iter);
     658          20 :       if (tmul_best == t_mulredc_2)
     659           0 :         fprintf (stderr, " *");
     660          20 :       fprintf (stderr, "\n");
     661             : #endif
     662             : #ifdef HAVE___GMPN_REDC_N
     663          20 :       if (redc_n_ok[N])
     664             :         {
     665           0 :           fprintf (stderr, "mul+redc_n = %.3f",
     666           0 :                    (double) t_mulredc_n * 1e3 / (double) iter);
     667           0 :           if (tmul_best == t_mulredc_n)
     668           0 :             fprintf (stderr, " *");
     669           0 :           fprintf (stderr, "\n");
     670             :     }
     671             :   else
     672          20 :     fprintf (stderr, "mul+redc_n = disabled\n");
     673             : #endif
     674             : 
     675          20 :       fprintf (stderr, "\n");
     676             : 
     677             :   /* modular squaring */
     678             : #ifdef USE_ASM_REDC
     679          20 :       fprintf (stderr, "mulredc    = %.3f",
     680          20 :                (double) t2 * 1e3 / (double) iter);
     681          20 :       if (tsqr_best == t2)
     682           4 :         fprintf (stderr, " *");
     683          20 :       fprintf (stderr, "\n");
     684             : #endif
     685             : #ifdef HAVE___GMPN_REDC_1
     686          20 :       fprintf (stderr, "sqr+redc_1 = %.3f",
     687          20 :                (double) t_sqrredc_1 * 1e3 / (double) iter);
     688          20 :       if (tsqr_best == t_sqrredc_1)
     689          16 :         fprintf (stderr, " *");
     690          20 :       fprintf (stderr, "\n");
     691             : #endif
     692             : #ifdef HAVE___GMPN_REDC_2
     693          20 :       fprintf (stderr, "sqr+redc_2 = %.3f",
     694          20 :                (double) t_sqrredc_2 * 1e3 / (double) iter);
     695          20 :       if (tsqr_best == t_sqrredc_2)
     696           0 :         fprintf (stderr, " *");
     697          20 :       fprintf (stderr, "\n");
     698             : #endif
     699             : #ifdef HAVE___GMPN_REDC_N
     700          20 :       if (redc_n_ok[N])
     701             :         {
     702           0 :           fprintf (stderr, "sqr+redc_n = %.3f",
     703           0 :                    (double) t_sqrredc_n * 1e3 / (double) iter);
     704           0 :           if (tsqr_best == t_sqrredc_n)
     705           0 :             fprintf (stderr, " *");
     706           0 :           fprintf (stderr, "\n");
     707             :         }
     708             :   else
     709          20 :     fprintf (stderr, "sqr+redc_n = disabled\n");
     710             : #endif
     711             : 
     712             : #ifdef HAVE_NATIVE_MULREDC1_N
     713             :       /* multiplication of n limbs by one limb */
     714          20 :       fprintf (stderr, "mulredc1   = %.3f\n",
     715          20 :                (double) t3 * 1e3 / (double) LOOPCOUNT);
     716             : #endif
     717          20 :       fflush (stderr);
     718             :     }
     719             :   
     720          20 :   free (tmp);
     721          20 :   free (x);
     722          20 :   free (y);
     723          20 :   free (z);
     724          20 :   free (zref);
     725          20 :   free (m);
     726          20 :   free (invm);
     727          20 : }
     728             : 
     729             : int
     730           1 : main (int argc, char** argv)
     731             : {
     732             :   int i;
     733           1 :   int minsize = 1, maxsize = MAXSIZE;
     734             : 
     735           1 :   if (argc >= 2 && strcmp (argv[1], "-v") == 0)
     736             :     {
     737           1 :       verbose = 1;
     738           1 :       argc --;
     739           1 :       argv ++;
     740             :     }
     741             : 
     742           1 :   if (argc > 1)
     743           0 :     minsize = atoi (argv[1]);
     744           1 :   if (argc > 2)
     745           0 :     maxsize = atoi (argv[2]);
     746             :   
     747          21 :   for (i = minsize; i <= maxsize; ++i)
     748          20 :     bench(i);
     749             : 
     750           1 :   printf ("/* 0:mulredc 1:mul+redc_1 2:mul+redc_2 3:mul+redc_n */\n");
     751           1 :   printf ("#define TUNE_MULREDC_TABLE {0");
     752          21 :   for (i = 1; i <= maxsize; i++)
     753          20 :     printf (",%d", tune_mul[i]);
     754           1 :   printf ("}\n");
     755           1 :   printf ("/* 0:mulredc 1:sqr+redc_1 2:sqr+redc_2 3:sqr+redc_n */\n");
     756           1 :   printf ("#define TUNE_SQRREDC_TABLE {0");
     757          21 :   for (i = 1; i <= maxsize; i++)
     758          20 :     printf (",%d", tune_sqr[i]);
     759           1 :   printf ("}\n");
     760           1 :   fflush (stdout);
     761             : 
     762           1 :   return 0;
     763             : }

Generated by: LCOV version 1.14