1 /*
2  * Copyright (C) 2002 David Defour, Catherine Daramy, and Florent de Dinechin
3  *
4  * This file is part of scslib, the Software Carry-Save multiple-precision
5  * library, which has been developed by the Arénaire project at École normale
6  * supérieure de Lyon.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 #include "scs.h"
25 #include "scs_private.h"
26 
27 /* Compile only if gmp is present */
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <math.h>
33 #include "tbx_timing.h"
34 #ifdef HAVE_GMP_H
35 #include <gmp.h>
36 #endif
37 #ifdef HAVE_MPFR_H
38 #include <mpfr.h>
39 #endif
40 
41 
42 #define LOOPS 1000
43 
44 
45 
46 /*
47  * Used to mesure time taken by the instruction "name"
48  */
49 #define TST_FCT(char, name)\
50          /* one untimed loop to load cache */ \
51          for(i=0; i< LOOPS-1; i++){ \
52            name;\
53            } \
54          TBX_GET_TICK(t1);\
55          for(i=0; i< LOOPS-1; i++){ \
56            name;\
57            } \
58          TBX_GET_TICK(t2);\
59 	 deltat = TBX_TICK_RAW_DIFF(t1, t2); \
60          printf("%28s :  %lld ticks,\t ratio to  FP +:  %f\n", char, deltat, (double) deltat/tadd);
61 
62 
63 /* Similar to the previous, computes the time for one FP add so that
64    we have something to normalize against */
65 #define COMPUTE_TADD()\
66          /* one untimed loop to load cache */ \
67          for(i=0; i< LOOPS-1; i++){ \
68            d3 = double_table[i]*double_table[i+1];\
69            } \
70          TBX_GET_TICK(t1);\
71          for(i=0; i< LOOPS-1; i++){ \
72            d3 = double_table[i]*double_table[i+1];\
73            } \
74          TBX_GET_TICK(t2);\
75 	 tadd = TBX_TICK_RAW_DIFF(t1, t2);
76 
77 
78 /*
79  * Fct de test .
80  */
main()81 int main(){
82   scs_t n1I;
83   volatile double d3;
84   volatile int int_r;
85   unsigned long long deltat,tadd;
86   tbx_tick_t   t1, t2;
87   int i;
88 
89   /* table storing random number */
90   scs_t  scs_table[LOOPS];
91 #ifdef HAVE_GMP_H
92   mpf_t  mpf_table[LOOPS];
93   mpf_t a;
94 #endif
95 #ifdef HAVE_MPFR_H
96   mpfr_t  mpfr_table[LOOPS];
97   mpfr_t  mpfr_a;
98 #endif
99 
100   double double_table[LOOPS];
101   int int_table[LOOPS];
102 
103 
104 
105   printf("Random generation  ... ");
106   srand(42);
107   for(i=0; i<LOOPS; i++){
108     scs_rand(scs_table[i], 7);
109 #if 1
110     scs_table[i]->sign = 1; /* only positive numbers */
111 #endif
112     scs_get_d(&double_table[i], scs_table[i]);
113     int_table[i] = double_table[i];
114 #ifdef HAVE_GMP_H
115     mpf_init2(mpf_table[i], (SCS_NB_BITS*SCS_NB_WORDS) );
116     scs_get_mpf(scs_table[i], mpf_table[i]);
117 #endif
118 #ifdef HAVE_MPFR_H
119     mpfr_init2(mpfr_table[i], (SCS_NB_BITS*SCS_NB_WORDS) );
120     scs_get_mpfr(scs_table[i], mpfr_table[i]);
121 #endif
122   }
123   printf(" done \n\n");
124 
125 
126 #ifdef HAVE_GMP_H
127   mpf_init2(a, (SCS_NB_BITS*SCS_NB_WORDS));
128   mpf_set(a, mpf_table[1]);
129 #endif
130 #ifdef HAVE_MPFR_H
131   mpfr_init2(mpfr_a, (SCS_NB_BITS*SCS_NB_WORDS));
132   mpfr_set(mpfr_a, mpfr_table[1], GMP_RNDN);
133 #endif
134 
135   printf("These first timings don't mean much\n");
136   COMPUTE_TADD()
137   TST_FCT("int a + b ", int_r = int_table[i]+int_table[i+1])
138   TST_FCT("int a * b ", d3 = int_table[i]*int_table[i+1])
139   TST_FCT("double a + b ", d3 = double_table[i]+double_table[i+1])
140   TST_FCT("double a * b ", d3 = double_table[i]*double_table[i+1])
141   TST_FCT("double a / b ", d3 = double_table[i]/double_table[i+1])
142   printf("\n");
143 
144   printf("Here come the meaningful timings\n");
145   /* scs library test */
146   TST_FCT("conversion scs=>doubles ", scs_get_d(&double_table[i], scs_table[i]))
147   TST_FCT("conversion doubles=>scs ", scs_set_d(n1I, double_table[i]))
148   TST_FCT("scs_add ", scs_add(n1I, scs_table[i], scs_table[i+1]))
149   TST_FCT("scs_sub ", scs_sub(n1I, scs_table[i], scs_table[i+1]))
150   TST_FCT("scs_add_no_renorm ",scs_add_no_renorm(n1I, scs_table[i], scs_table[i+1]))
151   TST_FCT("scs_mul ", scs_mul(n1I, scs_table[i], scs_table[i+1]))
152   TST_FCT("scs_mul_ui ", scs_mul_ui(scs_table[i], 31242436))
153   TST_FCT("scs_square  ", scs_square(n1I, scs_table[i]))
154     //  TST_FCT("scs_fma ", scs_fma(n1I, scs_table[i], scs_table[i], scs_table[i+1]))
155   TST_FCT("add + mul scs ", scs_mul(n1I, scs_table[i], scs_table[i+1]); scs_add(n1I, n1I, scs_table[i]))
156 
157   TST_FCT("renormalization scs ", scs_renorm(scs_table[i]))
158   TST_FCT("scs_div ", scs_div(n1I, scs_table[i], scs_table[i+1]))
159   printf("\n");
160 
161 #ifdef HAVE_GMP_H
162   /* mpf (gmp) library test */
163   TST_FCT("Conversion mpf=>double", double_table[i] = mpf_get_d(mpf_table[i]))
164   TST_FCT("Conversion double=>mpf ", mpf_set_d(a, double_table[i]))
165   TST_FCT("Addition mpf ", mpf_add(a, mpf_table[i], mpf_table[i+1]))
166   TST_FCT("Multiplication mpf ", mpf_mul(a, mpf_table[i], mpf_table[i+1]))
167   TST_FCT("Multiplication_with_int mpf ", mpf_mul_ui(a, mpf_table[i], 3254353))
168   TST_FCT("Division mpf ", mpf_div(a, mpf_table[i], mpf_table[i+1]))
169   printf("\n");
170 #endif
171 
172 
173 #ifdef HAVE_MPFR_H
174   /* mpf (gmp) library test */
175   TST_FCT("Conversion mpfr=>double", double_table[i] = mpfr_get_d(mpfr_table[i],GMP_RNDN))
176   TST_FCT("Conversion double=>mpfr ", mpfr_set_d(mpfr_a, double_table[i],GMP_RNDN))
177   TST_FCT("Addition mpfr ", mpfr_add(mpfr_a, mpfr_table[i], mpfr_table[i+1],GMP_RNDN))
178   TST_FCT("Multiplication mpfr ", mpfr_mul(mpfr_a, mpfr_table[i], mpfr_table[i+1],GMP_RNDN))
179   TST_FCT("Multiplication_with_int mpfr ", mpfr_mul_ui(mpfr_a, mpfr_table[i], 3254353,GMP_RNDN))
180   TST_FCT("Division mpfr ", mpfr_div(mpfr_a, mpfr_table[i], mpfr_table[i+1],GMP_RNDN))
181   printf("\n");
182 #endif
183 
184 
185 
186 
187   return 0;
188 }
189 
190