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