Changeset 1127 in Sophya for trunk/Eval/Speed/tompCXX.cc
- Timestamp:
- Aug 7, 2000, 10:58:19 AM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Eval/Speed/tompCXX.cc
r1098 r1127 1 /* ------ programme de test des capacites OpenMP ------ */ 2 /* Calcul parallele sur plusieurs processeurs */ 3 /* (C) R. Ansari LAL/IN2P3-CNRS 2000 */ 4 1 5 #include <stdlib.h> 2 6 #include <stdio.h> 3 7 #include <math.h> 8 9 #include <iostream.h> 10 11 #ifdef _OPENMP 12 #include <omp.h> 13 #endif 14 15 /* Declaration de fonctions de calcul de temps CPU - timg.h .c */ 4 16 extern "C" { 5 17 void InitTim(); … … 7 19 } 8 20 9 void Mult(int n, double *v1, double *v2, double *v3); 10 void MultOMP(int n, double *v1, double *v2, double *v3); 11 void MultOMP2(int N, int n, double *v1, double *v2, double *v3); 12 13 int main (int narg, char *arg[]) 14 { 15 int i,j, N, M; 16 17 double *v1, *v2, *v3; 18 21 /* Declaration des fonctions de ce fichier */ 22 void Mult(long n, double *v1, double *v2, double *v3); 23 void MultB(long b, double *v1, double *v2, double *v3); 24 void Check(long n, double *v3, double *v3ck); 25 void Mult_OMP(long n, double *v1, double *v2, double *v3); 26 void MultB_OMP(long b, double *v1, double *v2, double *v3); 27 void MultB_OMP2(long b, double *v1, double *v2, double *v3); 28 void MultB_OMP3(long b, double *v1, double *v2, double *v3); 29 // void getBlock(long b, long* off1, long* off2, long* off3, long* sz); C 30 void getBlock(long b, long& off1, long& off2, long& off3, long& sz); 31 void fillRandom(long n, double *v1, double *v2); 32 33 34 /* Variables statiques globales */ 35 static long M,N,B,BSz; 36 static int omp_nthr = 4; 37 38 /* --- main() --- */ 39 int main (long narg, char *arg[]) 40 { 41 long i; 42 43 double *v1, *v2, *v3, *v3ck; 19 44 if (narg < 2) { 20 printf("\n Usage tompCXX P/x [N M] \n \n"); 21 printf(" P -> Calling MultOMP2 p -> Calling MultOMP, x -> Calling Mult \n"); 22 printf(" N (=100): External loop number M : Array Size (500000) \n"); 23 exit(0); 24 } 25 N = 100; 26 M = 500000; 27 if (narg > 2) N = atoi(arg[2]); 28 if (narg > 3) M = atoi(arg[3]); 29 45 cout << "\n Usage tompCXX P/p/S/s [N BSz B OMP_NThr] (Test OpenMP) \n \n" 46 << " P /P2 /P3 -> Calling MultB_OMP /2/3 p -> Calling Mult_OMP \n" 47 << " S -> Calling MultB , s -> Calling Mult \n" 48 << " N (=10): External loop number BSz : BlockSize Size (50000) \n" 49 << " B : Nb of Blocks 100 \n" 50 << " OMP_NThr : Number of OpenMP threads (def = 4) \n " << endl; 51 return(0); 52 } 53 54 N = 10; 55 BSz = 50000; 56 B = 100; 57 if (narg > 2) N = atol(arg[2]); 58 if (narg > 3) BSz = atol(arg[3]); 59 if (narg > 4) B = atol(arg[4]); 60 61 M = B*BSz; 62 63 omp_nthr = 4; 64 if (narg > 5) omp_nthr = atol(arg[5]); 65 66 cout << " tompCXX : M (ArrSize)= " << M << " NLoop=" << N << " NBlock=" << B 67 << " BlockSize=" << BSz << endl; 68 30 69 InitTim(); 31 70 … … 33 72 v2 = new double[M]; 34 73 v3 = new double[M]; 35 36 for(i=0; i<M; i++) { v1[i] = random()%1000; v2[i] = random()%5000; } 74 v3ck = new double[M]; 75 76 /* Remplissage initiale */ 77 fillRandom(M, v1, v2); 78 Mult(M, v1, v2, v3ck); 79 37 80 PrtTim("End of Init "); 38 81 82 #ifdef _OPENMP 83 if ((*arg[1] == 'P') || (*arg[1] == 'p')) 84 { 85 omp_set_num_threads(omp_nthr); 86 printf(" tompC NumThreads= %d (Max=%d) NumProcs= %d \n", omp_get_num_threads(), 87 omp_get_max_threads(), omp_get_num_procs()); 88 } 89 #endif 90 91 /* Fonctions avec OpenMP */ 39 92 if (*arg[1] == 'P') { 40 printf("Calling MultOMP2(N=%d, Size= %d) \n", N, M); 41 MultOMP2(N, M, v1, v2, v3); 42 } 43 else if (*arg[1] == 'p') { 44 printf("Calling N=%d times MultOMP(Size= %d) \n", N, M); 45 for(i=0; i<N; i++) MultOMP(M, v1, v2, v3); 46 } 47 else { 93 if (*(arg[2]+1) == '2') { /* Double boucle - OpenMP parallel boucle externe */ 94 printf("Calling N=%d times MultB_OMP2(Size= %d) \n", N, M); 95 for(i=0; i<N; i++) { 96 MultB_OMP2(B, v1, v2, v3); 97 printf("%d ", i); fflush(stdout); 98 } 99 printf(" ... Done \n"); 100 } 101 else if (*(arg[2]+1) == '3') { /* Double boucle - Nested parallel */ 102 printf("Calling N=%d times MultB_OMP3(Size= %d) \n", N, M); 103 for(i=0; i<N; i++) { 104 MultB_OMP3(B, v1, v2, v3); 105 printf("%d ", i); fflush(stdout); 106 } 107 printf(" ... Done \n"); 108 } 109 else { /* boucle double - OpenMP parallel boucle externe */ 110 printf("Calling N=%d times MultB_OMP(Size= %d) \n", N, M); 111 for(i=0; i<N; i++) { 112 MultB_OMP(B, v1, v2, v3); 113 printf("%d ", i); fflush(stdout); 114 } 115 printf(" ... Done \n"); 116 } 117 } 118 else if (*arg[1] == 'p') { /* boucle simple - OpenMP */ 119 printf("Calling N=%d times Mult_OMP(Size= %d) \n", N, M); 120 for(i=0; i<N; i++) { 121 Mult_OMP(M, v1, v2, v3); 122 printf("%d ", i); fflush(stdout); 123 } 124 printf(" ... Done \n"); 125 } 126 127 /* Fonctions SANS OpenMP (scalaire) */ 128 else if (*arg[1] == 'S') { /* Double boucle */ 129 printf("Calling N=%d times MultB(Size= %d) \n", N, M); 130 for(i=0; i<N; i++) { 131 MultB(B, v1, v2, v3); 132 printf("%d ", i); fflush(stdout); 133 } 134 printf(" ... Done \n"); 135 } 136 else if (*arg[1] == 's') { /* Boucle simple */ 48 137 printf("Calling N=%d times Mult(Size= %d) \n", N, M); 49 for(i=0; i<N; i++) Mult(M, v1, v2, v3); 50 } 51 52 PrtTim("End of Multiplication "); 138 for(i=0; i<N; i++) { 139 Mult(M, v1, v2, v3); 140 printf("%d ", i); fflush(stdout); 141 } 142 printf(" ... Done \n"); 143 } 144 145 146 PrtTim("End of Mult-Operation "); 147 148 Check(M, v3, v3ck); 149 150 PrtTim("End of programme "); 53 151 54 152 delete[] v1; 55 153 delete[] v2; 56 154 delete[] v3; 57 exit(0); 58 } 59 60 61 void Mult(int n, double *v1, double *v2, double *v3) 62 { 63 int k; 155 delete[] v3ck; 156 157 return(0); 158 } 159 160 161 /* --Fonction-- */ 162 void fillRandom(long n, double *v1, double *v2) 163 /* Remplissage aleatoire de tableaux v1 v2 */ 164 { 165 long off,nn,k,i; 166 double x1; 167 long nbk = (B < 20) ? 20 : B; 168 nn = n/nbk; 169 for(k=0; k<nn; k++) { 170 v1[k] = random()%10000; 171 v2[k] = random()%14000; 172 } 173 for(i=1; i<nbk; i++) { 174 off = i*nn; 175 v1[k+off] = v1[k]; 176 v2[k+off] = v2[k]; 177 } 178 x1 = random()%18000; 179 if (nn*nbk < n) 180 for(k=nn*nbk; k<n; k++) v1[k] = v2[k] = x1; 181 182 return; 183 } 184 185 /* --Fonction-- */ 186 void getBlock(long b, long& off1, long& off2, long& off3, long& sz) 187 // void getBlock(long b, long* off1, long* off2, long* off3, long* sz) 188 /* Numero , offset de blocks */ 189 { 190 if ( (b < 0) || (b >= B) ) { 191 cerr << " ERROR getBlock( b= " << b << " ??? " << endl; 192 throw 999; 193 // printf(" ERROR getBlock( b= %ld ???? \n", b); 194 // exit(99); 195 } 196 sz = BSz; 197 off1 = off2 = off3 = b*BSz; 198 // *sz = BSz; 199 // *off1 = *off2 = *off3 = b*BSz; 200 201 return ; 202 } 203 204 /* --Fonction-- */ 205 void Check(long n, double *v3, double *v3ck) 206 /* Verification egalite v3 v3ck */ 207 { 208 long npb; 209 long k; 210 npb = 0; 211 for(k=0; k<n; k++) 212 if (fabs(v3[k]-v3ck[k]) > 1.e-39) npb++; 213 214 if (npb == 0) 215 // printf(" Check() - OK NPB=0 / N= %ld\n", n); 216 cout << " Check() - OK NPB=0 / N= " << n << endl; 217 else 218 // printf(" PB Check() !!! - OK NPB= %ld / N= %ld", npb,n); 219 cout << " PB Check() !!! - OK NPB= " << npb << " / N= " << n << endl; 220 } 221 222 223 /* --Fonction-- */ 224 void Mult(long n, double *v1, double *v2, double *v3) 225 /* Multiplication - boucle simple v3 = v1*v2 */ 226 { 227 long k; 64 228 for(k=0; k<n; k++) 65 229 v3[k] = v1[k] * v2[k]; 66 230 } 67 231 68 void MultOMP(int n, double *v1, double *v2, double *v3) 69 { 70 int k; 71 #pragma omp parallel for 232 233 /* --Fonction-- */ 234 void Mult_OMP(long n, double *v1, double *v2, double *v3) 235 /* Multiplication - boucle simple - OpenMP v3 = v1*v2 */ 236 { 237 long k; 238 #ifdef _OPENMP 239 omp_set_num_threads(omp_nthr); 240 #pragma omp parallel for schedule(static) 241 #endif 72 242 for(k=0; k<n; k++) 73 243 v3[k] = v1[k] * v2[k]; 74 244 } 75 void MultOMP2(int N, int n, double *v1, double *v2, double *v3) 76 { 77 int k; 78 int i; 79 #pragma omp parallel default(shared) 80 { 81 #pragma omp parallel for 82 for(i=0; i<N; i++) 83 #pragma omp parallel for 84 for(k=0; k<n; k++) 85 v3[k] = v1[k] * v2[k]; 86 } 87 } 245 246 247 /* --Fonction-- */ 248 void MultB(long b, double *vv1, double *vv2, double *vv3) 249 /* Multiplication - boucle double (par block) v3 = v1*v2 */ 250 { 251 long k,i; 252 long sz, off1,off2,off3; 253 double *v1, *v2, *v3; 254 for(k=0; k<b; k++) { 255 // getBlock(k, &off1, &off2, &off3, &sz); 256 getBlock(k, off1, off2, off3, sz); 257 v1 = vv1+off1; 258 v2 = vv2+off2; 259 v3 = vv3+off3; 260 for(i=0; i<sz; i++) 261 v3[i] = v1[i] * v2[i]; 262 } 263 } 264 265 /* --Fonction-- */ 266 void MultB_OMP(long b, double *vv1, double *vv2, double *vv3) 267 /* Multiplication - boucle double (par block) - OpenMP v3 = v1*v2 */ 268 { 269 long k,i,ub; 270 long sz, off1,off2,off3; 271 double *v1, *v2, *v3; 272 273 ub = b; 274 #ifdef _OPENMP 275 if (b>1) 276 omp_set_num_threads((b<omp_nthr)?b:omp_nthr); 277 #pragma omp parallel for if(b>1) private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static) 278 #endif 279 for(k=0; k<ub; k++) { 280 // getBlock(k, &off1, &off2, &off3, &sz); 281 getBlock(k, off1, off2, off3, sz); 282 v1 = vv1+off1; 283 v2 = vv2+off2; 284 v3 = vv3+off3; 285 for(i=0; i<sz; i++) 286 v3[i] = v1[i] * v2[i]; 287 } 288 } 289 290 /* --Fonction-- */ 291 void MultB_OMP2(long b, double *vv1, double *vv2, double *vv3) 292 /* Multiplication - boucle double (par block) - OpenMP v3 = v1*v2 */ 293 { 294 long k,i; 295 long sz, off1,off2,off3; 296 double *v1, *v2, *v3; 297 #ifdef _OPENMP 298 if (b>1) 299 omp_set_num_threads((b<omp_nthr)?b:omp_nthr); 300 #pragma omp parallel if(b>1) 301 { 302 #pragma omp single 303 printf("MultB_OMP2() NumThr= %d \n", omp_get_num_threads()); 304 #pragma omp for private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static) 305 #endif 306 for(k=0; k<b; k++) { 307 // getBlock(k, &off1, &off2, &off3, &sz); 308 getBlock(k, off1, off2, off3, sz); 309 v1 = vv1+off1; 310 v2 = vv2+off2; 311 v3 = vv3+off3; 312 for(i=0; i<sz; i++) 313 v3[i] = v1[i] * v2[i]; 314 } 315 #ifdef _OPENMP 316 } 317 #endif 318 319 } 320 321 /* --Fonction-- */ 322 void MultB_OMP3(long b, double *vv1, double *vv2, double *vv3) 323 /* Multiplication - boucle double (par block) - OpenMP v3 = v1*v2 */ 324 { 325 long k,i; 326 long sz, off1,off2,off3; 327 double *v1, *v2, *v3; 328 #ifdef _OPENMP 329 if (b>1) 330 omp_set_num_threads((b<omp_nthr)?b:omp_nthr); 331 #pragma omp parallel if(b>1) 332 { 333 #pragma omp single 334 printf("MultB_OMP3() NumThr= %d \n", omp_get_num_threads()); 335 #pragma omp for private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static) 336 #endif 337 for(k=0; k<b; k++) { 338 // getBlock(k, &off1, &off2, &off3, &sz); 339 getBlock(k, off1, off2, off3, sz); 340 v1 = vv1+off1; 341 v2 = vv2+off2; 342 v3 = vv3+off3; 343 #ifdef _OPENMP 344 #pragma omp parallel 345 { 346 #pragma omp single 347 if (k==0) printf("MultB_OMP3() -pragma2- NumThr= %d \n", omp_get_num_threads()); 348 #pragma omp for private(i) schedule(static) 349 #endif 350 for(i=0; i<sz; i++) 351 v3[i] = v1[i] * v2[i]; 352 #ifdef _OPENMP 353 } 354 #endif 355 } 356 #ifdef _OPENMP 357 } 358 #endif 359 360 } 361
Note:
See TracChangeset
for help on using the changeset viewer.