1 2 #include <petscsys.h> 3 #include <petsctime.h> 4 5 extern int BlastCache(void); 6 extern int test1(void); 7 extern int test2(void); 8 9 int main(int argc,char **argv) 10 { 11 12 PetscCall(PetscInitialize(&argc,&argv,0,0)); 13 PetscCall(test1()); 14 PetscCall(test2()); 15 PetscCall(PetscFinalize()); 16 return 0; 17 } 18 19 int test1(void) 20 { 21 PetscLogDouble t1,t2; 22 double value; 23 int i,ierr,*z,*zi,intval; 24 PetscScalar *x,*y; 25 PetscRandom r; 26 27 PetscCall(PetscRandomCreate(PETSC_COMM_SELF,&r)); 28 PetscCall(PetscRandomSetFromOptions(r)); 29 PetscCall(PetscMalloc1(20000,&x)); 30 PetscCall(PetscMalloc1(20000,&y)); 31 32 PetscCall(PetscMalloc1(2000,&z)); 33 PetscCall(PetscMalloc1(2000,&zi)); 34 35 /* Take care of paging effects */ 36 PetscCall(PetscTime(&t1)); 37 38 /* Form the random set of integers */ 39 for (i=0; i<2000; i++) { 40 PetscCall(PetscRandomGetValue(r,&value)); 41 intval = (int)(value*20000.0); 42 z[i] = intval; 43 } 44 45 for (i=0; i<2000; i++) { 46 PetscCall(PetscRandomGetValue(r,&value)); 47 intval = (int)(value*20000.0); 48 zi[i] = intval; 49 } 50 /* fprintf(stdout,"Done setup\n"); */ 51 52 PetscCall(BlastCache()); 53 54 PetscCall(PetscTime(&t1)); 55 for (i=0; i<2000; i++) x[i] = y[i]; 56 PetscCall(PetscTime(&t2)); 57 fprintf(stdout,"%-27s : %e sec\n","x[i] = y[i]",(t2-t1)/2000.0); 58 59 PetscCall(BlastCache()); 60 61 PetscCall(PetscTime(&t1)); 62 for (i=0; i<500; i+=4) { 63 x[i] = y[z[i]]; 64 x[1+i] = y[z[1+i]]; 65 x[2+i] = y[z[2+i]]; 66 x[3+i] = y[z[3+i]]; 67 } 68 PetscCall(PetscTime(&t2)); 69 fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]] - unroll 4",(t2-t1)/2000.0); 70 71 PetscCall(BlastCache()); 72 73 PetscCall(PetscTime(&t1)); 74 for (i=0; i<2000; i++) x[i] = y[z[i]]; 75 PetscCall(PetscTime(&t2)); 76 fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]]",(t2-t1)/2000.0); 77 78 PetscCall(BlastCache()); 79 80 PetscCall(PetscTime(&t1)); 81 for (i=0; i<1000; i+=2) { x[i] = y[z[i]]; x[1+i] = y[z[1+i]]; } 82 PetscCall(PetscTime(&t2)); 83 fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]] - unroll 2",(t2-t1)/2000.0); 84 85 PetscCall(BlastCache()); 86 87 PetscCall(PetscTime(&t1)); 88 for (i=0; i<2000; i++) x[z[i]] = y[i]; 89 PetscCall(PetscTime(&t2)); 90 fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[i]",(t2-t1)/2000.0); 91 92 PetscCall(BlastCache()); 93 94 PetscCall(PetscTime(&t1)); 95 for (i=0; i<2000; i++) x[z[i]] = y[zi[i]]; 96 PetscCall(PetscTime(&t2)); 97 fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[zi[i]]",(t2-t1)/2000.0); 98 99 PetscCall(PetscArraycpy(x,y,10)); 100 PetscCall(PetscArraycpy(z,zi,10)); 101 PetscCall(PetscFree(z)); 102 PetscCall(PetscFree(zi)); 103 PetscCall(PetscFree(x)); 104 PetscCall(PetscFree(y)); 105 PetscCall(PetscRandomDestroy(&r)); 106 PetscFunctionReturn(0); 107 } 108 109 int test2(void) 110 { 111 PetscLogDouble t1,t2; 112 double value; 113 int i,ierr,z[20000],zi[20000],intval,tmp; 114 PetscScalar x[20000],y[20000]; 115 PetscRandom r; 116 117 PetscCall(PetscRandomCreate(PETSC_COMM_SELF,&r)); 118 PetscCall(PetscRandomSetFromOptions(r)); 119 120 /* Take care of paging effects */ 121 PetscCall(PetscTime(&t1)); 122 123 for (i=0; i<20000; i++) { 124 x[i] = i; 125 y[i] = i; 126 z[i] = i; 127 zi[i] = i; 128 } 129 130 /* Form the random set of integers */ 131 for (i=0; i<20000; i++) { 132 PetscCall(PetscRandomGetValue(r,&value)); 133 intval = (int)(value*20000.0); 134 tmp = z[i]; 135 z[i] = z[intval]; 136 z[intval] = tmp; 137 } 138 139 for (i=0; i<20000; i++) { 140 PetscCall(PetscRandomGetValue(r,&value)); 141 intval = (int)(value*20000.0); 142 tmp = zi[i]; 143 zi[i] = zi[intval]; 144 zi[intval] = tmp; 145 } 146 /* fprintf(stdout,"Done setup\n"); */ 147 148 /* PetscCall(BlastCache()); */ 149 150 PetscCall(PetscTime(&t1)); 151 for (i=0; i<2000; i++) x[i] = y[i]; 152 PetscCall(PetscTime(&t2)); 153 fprintf(stdout,"%-27s : %e sec\n","x[i] = y[i]",(t2-t1)/2000.0); 154 155 /* PetscCall(BlastCache()); */ 156 157 PetscCall(PetscTime(&t1)); 158 for (i=0; i<2000; i++) y[i] = x[z[i]]; 159 PetscCall(PetscTime(&t2)); 160 fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]]",(t2-t1)/2000.0); 161 162 /* PetscCall(BlastCache()); */ 163 164 PetscCall(PetscTime(&t1)); 165 for (i=0; i<2000; i++) x[z[i]] = y[i]; 166 PetscCall(PetscTime(&t2)); 167 fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[i]",(t2-t1)/2000.0); 168 169 /* PetscCall(BlastCache()); */ 170 171 PetscCall(PetscTime(&t1)); 172 for (i=0; i<2000; i++) y[z[i]] = x[zi[i]]; 173 PetscCall(PetscTime(&t2)); 174 fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[zi[i]]",(t2-t1)/2000.0); 175 176 PetscCall(PetscRandomDestroy(&r)); 177 PetscFunctionReturn(0); 178 } 179 180 int BlastCache(void) 181 { 182 int i,ierr,n = 1000000; 183 PetscScalar *x,*y,*z,*a,*b; 184 185 PetscCall(PetscMalloc1(5*n,&x)); 186 y = x + n; 187 z = y + n; 188 a = z + n; 189 b = a + n; 190 191 for (i=0; i<n; i++) { 192 a[i] = (PetscScalar) i; 193 y[i] = (PetscScalar) i; 194 z[i] = (PetscScalar) i; 195 b[i] = (PetscScalar) i; 196 x[i] = (PetscScalar) i; 197 } 198 199 for (i=0; i<n; i++) a[i] = 3.0*x[i] + 2.0*y[i] + 3.3*z[i] - 25.*b[i]; 200 for (i=0; i<n; i++) b[i] = 3.0*x[i] + 2.0*y[i] + 3.3*a[i] - 25.*b[i]; 201 for (i=0; i<n; i++) z[i] = 3.0*x[i] + 2.0*y[i] + 3.3*a[i] - 25.*b[i]; 202 PetscCall(PetscFree(x)); 203 PetscFunctionReturn(0); 204 } 205