Actual source code: Index.c

  1: #include <petscsys.h>
  2: #include <petsctime.h>

  4: extern int BlastCache(void);
  5: extern int test1(void);
  6: extern int test2(void);

  8: int main(int argc,char **argv)
  9: {

 11:   PetscCall(PetscInitialize(&argc,&argv,0,0));
 12:   PetscCall(test1());
 13:   PetscCall(test2());
 14:   PetscCall(PetscFinalize());
 15:   return 0;
 16: }

 18: int test1(void)
 19: {
 20:   PetscLogDouble t1,t2;
 21:   double         value;
 22:   int            i,ierr,*z,*zi,intval;
 23:   PetscScalar    *x,*y;
 24:   PetscRandom    r;

 26:   PetscCall(PetscRandomCreate(PETSC_COMM_SELF,&r));
 27:   PetscCall(PetscRandomSetFromOptions(r));
 28:   PetscCall(PetscMalloc1(20000,&x));
 29:   PetscCall(PetscMalloc1(20000,&y));

 31:   PetscCall(PetscMalloc1(2000,&z));
 32:   PetscCall(PetscMalloc1(2000,&zi));

 34:   /* Take care of paging effects */
 35:   PetscCall(PetscTime(&t1));

 37:   /* Form the random set of integers */
 38:   for (i=0; i<2000; i++) {
 39:     PetscCall(PetscRandomGetValue(r,&value));
 40:     intval = (int)(value*20000.0);
 41:     z[i]   = intval;
 42:   }

 44:   for (i=0; i<2000; i++) {
 45:     PetscCall(PetscRandomGetValue(r,&value));
 46:     intval = (int)(value*20000.0);
 47:     zi[i]  = intval;
 48:   }
 49:   /* fprintf(stdout,"Done setup\n"); */

 51:   PetscCall(BlastCache());

 53:   PetscCall(PetscTime(&t1));
 54:   for (i=0; i<2000; i++) x[i] = y[i];
 55:   PetscCall(PetscTime(&t2));
 56:   fprintf(stdout,"%-27s : %e sec\n","x[i] = y[i]",(t2-t1)/2000.0);

 58:   PetscCall(BlastCache());

 60:   PetscCall(PetscTime(&t1));
 61:   for (i=0; i<500; i+=4) {
 62:     x[i]   = y[z[i]];
 63:     x[1+i] = y[z[1+i]];
 64:     x[2+i] = y[z[2+i]];
 65:     x[3+i] = y[z[3+i]];
 66:   }
 67:   PetscCall(PetscTime(&t2));
 68:   fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]] - unroll 4",(t2-t1)/2000.0);

 70:   PetscCall(BlastCache());

 72:   PetscCall(PetscTime(&t1));
 73:   for (i=0; i<2000; i++) x[i] = y[z[i]];
 74:   PetscCall(PetscTime(&t2));
 75:   fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]]",(t2-t1)/2000.0);

 77:   PetscCall(BlastCache());

 79:   PetscCall(PetscTime(&t1));
 80:   for (i=0; i<1000; i+=2) {  x[i] = y[z[i]];  x[1+i] = y[z[1+i]]; }
 81:   PetscCall(PetscTime(&t2));
 82:   fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]] - unroll 2",(t2-t1)/2000.0);

 84:   PetscCall(BlastCache());

 86:   PetscCall(PetscTime(&t1));
 87:   for (i=0; i<2000; i++) x[z[i]] = y[i];
 88:   PetscCall(PetscTime(&t2));
 89:   fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[i]",(t2-t1)/2000.0);

 91:   PetscCall(BlastCache());

 93:   PetscCall(PetscTime(&t1));
 94:   for (i=0; i<2000; i++) x[z[i]] = y[zi[i]];
 95:   PetscCall(PetscTime(&t2));
 96:   fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[zi[i]]",(t2-t1)/2000.0);

 98:   PetscCall(PetscArraycpy(x,y,10));
 99:   PetscCall(PetscArraycpy(z,zi,10));
100:   PetscCall(PetscFree(z));
101:   PetscCall(PetscFree(zi));
102:   PetscCall(PetscFree(x));
103:   PetscCall(PetscFree(y));
104:   PetscCall(PetscRandomDestroy(&r));
105:   PetscFunctionReturn(PETSC_SUCCESS);
106: }

108: int test2(void)
109: {
110:   PetscLogDouble t1,t2;
111:   double         value;
112:   int            i,ierr,z[20000],zi[20000],intval,tmp;
113:   PetscScalar    x[20000],y[20000];
114:   PetscRandom    r;

116:   PetscCall(PetscRandomCreate(PETSC_COMM_SELF,&r));
117:   PetscCall(PetscRandomSetFromOptions(r));

119:   /* Take care of paging effects */
120:   PetscCall(PetscTime(&t1));

122:   for (i=0; i<20000; i++) {
123:     x[i]  = i;
124:     y[i]  = i;
125:     z[i]  = i;
126:     zi[i] = i;
127:   }

129:   /* Form the random set of integers */
130:   for (i=0; i<20000; i++) {
131:     PetscCall(PetscRandomGetValue(r,&value));
132:     intval    = (int)(value*20000.0);
133:     tmp       = z[i];
134:     z[i]      = z[intval];
135:     z[intval] = tmp;
136:   }

138:   for (i=0; i<20000; i++) {
139:     PetscCall(PetscRandomGetValue(r,&value));
140:     intval     = (int)(value*20000.0);
141:     tmp        = zi[i];
142:     zi[i]      = zi[intval];
143:     zi[intval] = tmp;
144:   }
145:   /* fprintf(stdout,"Done setup\n"); */

147:   /* PetscCall(BlastCache()); */

149:   PetscCall(PetscTime(&t1));
150:   for (i=0; i<2000; i++) x[i] = y[i];
151:   PetscCall(PetscTime(&t2));
152:   fprintf(stdout,"%-27s : %e sec\n","x[i] = y[i]",(t2-t1)/2000.0);

154:   /* PetscCall(BlastCache()); */

156:   PetscCall(PetscTime(&t1));
157:   for (i=0; i<2000; i++) y[i] = x[z[i]];
158:   PetscCall(PetscTime(&t2));
159:   fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]]",(t2-t1)/2000.0);

161:   /* PetscCall(BlastCache()); */

163:   PetscCall(PetscTime(&t1));
164:   for (i=0; i<2000; i++) x[z[i]] = y[i];
165:   PetscCall(PetscTime(&t2));
166:   fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[i]",(t2-t1)/2000.0);

168:   /* PetscCall(BlastCache()); */

170:   PetscCall(PetscTime(&t1));
171:   for (i=0; i<2000; i++) y[z[i]] = x[zi[i]];
172:   PetscCall(PetscTime(&t2));
173:   fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[zi[i]]",(t2-t1)/2000.0);

175:   PetscCall(PetscRandomDestroy(&r));
176:   PetscFunctionReturn(PETSC_SUCCESS);
177: }

179: int BlastCache(void)
180: {
181:   int         i,ierr,n = 1000000;
182:   PetscScalar *x,*y,*z,*a,*b;

184:   PetscCall(PetscMalloc1(5*n,&x));
185:   y    = x + n;
186:   z    = y + n;
187:   a    = z + n;
188:   b    = a + n;

190:   for (i=0; i<n; i++) {
191:     a[i] = (PetscScalar) i;
192:     y[i] = (PetscScalar) i;
193:     z[i] = (PetscScalar) i;
194:     b[i] = (PetscScalar) i;
195:     x[i] = (PetscScalar) i;
196:   }

198:   for (i=0; i<n; i++) a[i] = 3.0*x[i] + 2.0*y[i] + 3.3*z[i] - 25.*b[i];
199:   for (i=0; i<n; i++) b[i] = 3.0*x[i] + 2.0*y[i] + 3.3*a[i] - 25.*b[i];
200:   for (i=0; i<n; i++) z[i] = 3.0*x[i] + 2.0*y[i] + 3.3*a[i] - 25.*b[i];
201:   PetscCall(PetscFree(x));
202:   PetscFunctionReturn(PETSC_SUCCESS);
203: }