1 #include <petscsys.h> 2 #include <petsctime.h> 3 4 extern int BlastCache(void); 5 extern int test1(void); 6 extern int test2(void); 7 8 int main(int argc,char **argv) 9 { 10 11 PetscCall(PetscInitialize(&argc,&argv,0,0)); 12 PetscCall(test1()); 13 PetscCall(test2()); 14 PetscCall(PetscFinalize()); 15 return 0; 16 } 17 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; 25 26 PetscCall(PetscRandomCreate(PETSC_COMM_SELF,&r)); 27 PetscCall(PetscRandomSetFromOptions(r)); 28 PetscCall(PetscMalloc1(20000,&x)); 29 PetscCall(PetscMalloc1(20000,&y)); 30 31 PetscCall(PetscMalloc1(2000,&z)); 32 PetscCall(PetscMalloc1(2000,&zi)); 33 34 /* Take care of paging effects */ 35 PetscCall(PetscTime(&t1)); 36 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 } 43 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"); */ 50 51 PetscCall(BlastCache()); 52 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); 57 58 PetscCall(BlastCache()); 59 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); 69 70 PetscCall(BlastCache()); 71 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); 76 77 PetscCall(BlastCache()); 78 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); 83 84 PetscCall(BlastCache()); 85 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); 90 91 PetscCall(BlastCache()); 92 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); 97 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 } 107 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; 115 116 PetscCall(PetscRandomCreate(PETSC_COMM_SELF,&r)); 117 PetscCall(PetscRandomSetFromOptions(r)); 118 119 /* Take care of paging effects */ 120 PetscCall(PetscTime(&t1)); 121 122 for (i=0; i<20000; i++) { 123 x[i] = i; 124 y[i] = i; 125 z[i] = i; 126 zi[i] = i; 127 } 128 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 } 137 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"); */ 146 147 /* PetscCall(BlastCache()); */ 148 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); 153 154 /* PetscCall(BlastCache()); */ 155 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); 160 161 /* PetscCall(BlastCache()); */ 162 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); 167 168 /* PetscCall(BlastCache()); */ 169 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); 174 175 PetscCall(PetscRandomDestroy(&r)); 176 PetscFunctionReturn(PETSC_SUCCESS); 177 } 178 179 int BlastCache(void) 180 { 181 int i,ierr,n = 1000000; 182 PetscScalar *x,*y,*z,*a,*b; 183 184 PetscCall(PetscMalloc1(5*n,&x)); 185 y = x + n; 186 z = y + n; 187 a = z + n; 188 b = a + n; 189 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 } 197 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 } 204