Changeset 24d6572 for tests/PRNG.cfa
- Timestamp:
- Jun 12, 2023, 2:45:32 PM (2 years ago)
- Branches:
- ast-experimental, master
- Children:
- 62d62db
- Parents:
- 34b4268 (diff), 251ce80 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tests/PRNG.cfa
r34b4268 r24d6572 1 // -*- Mode: C -*- 2 // 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo 4 // 5 // PRNG.c -- 6 // 3 // 4 // PRNG.c -- high-perforamnce pseudo-random numbers 5 // 6 // The contents of this file are covered under the licence agreement in the 7 // file "LICENCE" distributed with Cforall. 8 // 7 9 // Author : Peter A. Buhr 8 10 // Created On : Wed Dec 29 09:38:12 2021 9 11 // Last Modified By : Peter A. Buhr 10 // Last Modified On : T ue Nov 22 22:51:12 202211 // Update Count : 38112 // Last Modified On : Thu May 25 15:39:52 2023 13 // Update Count : 422 12 14 // 13 15 … … 15 17 #include <stdlib.hfa> // PRNG 16 18 #include <clock.hfa> 17 #include <thread.hfa>18 19 #include <limits.hfa> // MAX 19 20 #include <math.hfa> // sqrt 20 21 #include <malloc.h> // malloc_stats 21 22 #include <locale.h> // setlocale 23 #include <thread.hfa> 22 24 #include <mutex_stmt.hfa> 23 25 24 #ifdef __x86_64__ // 64-bit architecture 26 #define xstr(s) str(s) 27 #define str(s) #s 28 29 #if defined( __x86_64__ ) || defined( __aarch64__ ) // 64-bit architecture 25 30 #define PRNG PRNG64 26 31 #else // 32-bit architecture 27 32 #define PRNG PRNG32 28 33 #endif // __x86_64__ 34 35 //#define TIME 29 36 30 37 #ifdef TIME // use -O2 -nodebug … … 38 45 #endif // TIME 39 46 40 void avgstd( unsigned int buckets[] ) {41 unsigned int min = MAX, max = 0;47 static void avgstd( size_t trials, size_t buckets[] ) { 48 size_t min = MAX, max = 0; 42 49 double sum = 0.0, diff; 43 50 for ( i; BUCKETS ) { … … 54 61 } // for 55 62 double std = sqrt( sum / BUCKETS ); 56 mutex( sout ) sout | "trials" | TRIALS| "buckets" | BUCKETS63 mutex( sout ) sout | "trials" | trials | "buckets" | BUCKETS 57 64 | "min" | min | "max" | max 58 65 | "avg" | wd(0,1, avg) | "std" | wd(0,1, std) | "rstd" | wd(0,1, (avg == 0 ? 0.0 : std / avg * 100)) | "%"; … … 60 67 61 68 62 unsigned int seed = 1009;69 size_t seed = 1009; 63 70 64 71 thread T1 {}; 65 72 void main( T1 & ) { 66 unsigned int * buckets = calloc( BUCKETS );// too big for task stack67 for ( TRIALS / 100 ) {73 size_t * buckets = calloc( BUCKETS ); // too big for task stack 74 for ( TRIALS / 50 ) { 68 75 buckets[rand() % BUCKETS] += 1; // concurrent 69 76 } // for 70 avgstd( buckets );77 avgstd( TRIALS / 50, buckets ); 71 78 free( buckets ); 72 79 } // main … … 76 83 PRNG prng; 77 84 if ( seed != 0 ) set_seed( prng, seed ); 78 unsigned int * buckets = calloc( BUCKETS );// too big for task stack85 size_t * buckets = calloc( BUCKETS ); // too big for task stack 79 86 for ( TRIALS ) { 80 87 buckets[prng( prng ) % BUCKETS] += 1; // concurrent 81 88 } // for 82 avgstd( buckets );89 avgstd( TRIALS, buckets ); 83 90 free( buckets ); 84 91 } // main … … 86 93 thread T3 {}; 87 94 void main( T3 & th ) { 88 unsigned int * buckets = calloc( BUCKETS );// too big for task stack89 for ( TRIALS ) {95 size_t * buckets = calloc( BUCKETS ); // too big for task stack 96 for ( TRIALS / 5 ) { 90 97 buckets[prng() % BUCKETS] += 1; // concurrent 91 98 } // for 92 avgstd( buckets );99 avgstd( TRIALS / 5, buckets ); 93 100 free( buckets ); 94 101 } // main … … 96 103 thread T4 {}; 97 104 void main( T4 & th ) { 98 unsigned int * buckets = calloc( BUCKETS );// too big for task stack105 size_t * buckets = calloc( BUCKETS ); // too big for task stack 99 106 for ( TRIALS ) { 100 buckets[prng( th ) % BUCKETS] += 1; // concurrent101 } // for 102 avgstd( buckets );107 buckets[prng( th ) % BUCKETS] += 1; // concurrent 108 } // for 109 avgstd( TRIALS, buckets ); 103 110 free( buckets ); 104 111 } // main … … 108 115 static void dummy( thread$ & th ) __attribute__(( noinline )); 109 116 static void dummy( thread$ & th ) { 110 unsigned int * buckets = (unsigned int *)calloc( BUCKETS, sizeof(unsigned int) ); // too big for task stack111 for ( unsigned int i = 0; i < TRIALS; i += 1 ) {117 size_t * buckets = (size_t *)calloc( BUCKETS, sizeof(size_t) ); // too big for task stack 118 for ( size_t i = 0; i < TRIALS; i += 1 ) { 112 119 buckets[prng( th ) % BUCKETS] += 1; // sequential 113 120 } // for 114 avgstd( buckets );121 avgstd( TRIALS, buckets ); 115 122 free( buckets ); 116 123 } // dummy 117 124 125 118 126 int main() { 119 // causes leaked storage message 120 // setlocale( LC_NUMERIC, getenv( "LANG" ) ); // print digit separator 127 // setlocale( LC_NUMERIC, getenv( "LANG" ) ); // causes leaked storage message 128 129 // only works on the current pthread thread 130 // locale_t loc = newlocale( LC_NUMERIC_MASK, getenv( "LANG" ), (locale_t)0p ); 131 // if ( loc == (locale_t)0p ) abort( "newlocale" ); 132 // uselocale( loc ); 121 133 122 134 enum { TASKS = 4 }; 123 135 Time start; 136 124 137 #ifdef TIME // too slow for test and generates non-repeatable results 125 138 #if 1 126 unsigned int rseed; 139 sout | "glib rand" | nl | nl; 140 141 size_t rseed; 127 142 if ( seed != 0 ) rseed = seed; 128 143 else rseed = rdtscl(); … … 130 145 131 146 sout | sepDisable; 132 sout | wd(13, "rand()" ) | wd(10, "rand(5)") | wd(13, "rand(0,5)" );133 for ( 20 ) { 134 sout | wd( 13, rand()) | nonl;135 sout | wd(1 0, rand() % 5) | nonl;136 sout | wd(1 3, rand() % (5 - 0 + 1) + 0);147 sout | nl | wd(26, "rand()" ) | wd(12, "rand(5)") | wd(12, "rand(0,5)" ); 148 for ( 20 ) { 149 sout | wd(26, rand()) | nonl; 150 sout | wd(12, rand() % 5) | nonl; 151 sout | wd(12, rand() % (5 - 0 + 1) + 0); 137 152 } // for 138 153 sout | sepEnable; … … 142 157 STARTTIME; 143 158 { 144 unsigned int * buckets = calloc( BUCKETS );// too big for task stack145 for ( i; TRIALS / 10) {159 size_t * buckets = calloc( BUCKETS ); // too big for task stack 160 for ( i; TRIALS / 5 ) { 146 161 buckets[rand() % BUCKETS] += 1; // sequential 147 162 } // for 148 avgstd( buckets );163 avgstd( TRIALS / 5, buckets ); 149 164 free( buckets ); 150 165 } 151 ENDTIME( " x 10" );166 ENDTIME( " x 5 " ); 152 167 153 168 sout | nl | "Concurrent"; … … 159 174 } // wait for threads to complete 160 175 } 161 ENDTIME( " x 100 " );176 ENDTIME( " x 50 " ); 162 177 #endif // 0 163 178 #endif // TIME 179 180 sout | nl | "CFA " xstr(PRNG_NAME); 181 164 182 #if 1 165 183 PRNG prng; … … 168 186 169 187 sout | sepDisable; 170 sout | nl | wd( 13, "PRNG()" ) | wd(10, "PRNG(5)") | wd(13, "PRNG(0,5)" );171 for ( 20 ) { 172 sout | wd( 13, prng( prng )) | nonl; // cascading => side-effect functions called in arbitary order173 sout | wd(1 0, prng( prng, 5 )) | nonl;174 sout | wd(1 3, prng( prng, 0, 5 ));188 sout | nl | wd(26, "PRNG()" ) | wd(12, "PRNG(5)") | wd(12, "PRNG(0,5)" ); 189 for ( 20 ) { 190 sout | wd(26, prng( prng )) | nonl; // cascading => side-effect functions called in arbitary order 191 sout | wd(12, prng( prng, 5 )) | nonl; 192 sout | wd(12, prng( prng, 0, 5 )); 175 193 } // for 176 194 sout | sepEnable; … … 180 198 STARTTIME; 181 199 { 182 unsigned int * buckets = calloc( BUCKETS );// too big for task stack200 size_t * buckets = calloc( BUCKETS ); // too big for task stack 183 201 for ( TRIALS ) { 184 202 buckets[prng( prng ) % BUCKETS] += 1; // sequential 185 203 } // for 186 avgstd( buckets );204 avgstd( TRIALS, buckets ); 187 205 free( buckets ); 188 206 } … … 203 221 204 222 sout | sepDisable; 205 sout | nl | wd( 13, "prng()" ) | wd(10, "prng(5)") | wd(13, "prng(0,5)" );206 for ( 20 ) { 207 sout | wd( 13, prng()) | nonl; // cascading => side-effect functions called in arbitary order208 sout | wd(1 0, prng( 5 )) | nonl;209 sout | wd(1 3, prng( 0, 5 ));223 sout | nl | wd(26, "prng()" ) | wd(12, "prng(5)") | wd(12, "prng(0,5)" ); 224 for ( 20 ) { 225 sout | wd(26, prng()) | nonl; // cascading => side-effect functions called in arbitary order 226 sout | wd(12, prng( 5 )) | nonl; 227 sout | wd(12, prng( 0, 5 )); 210 228 } // for 211 229 sout | sepEnable; … … 215 233 STARTTIME; 216 234 { 217 unsigned int * buckets = calloc( BUCKETS );// too big for task stack218 for ( TRIALS ) {235 size_t * buckets = calloc( BUCKETS ); // too big for task stack 236 for ( TRIALS / 5 ) { 219 237 buckets[prng() % BUCKETS] += 1; 220 238 } // for 221 avgstd( buckets );239 avgstd( TRIALS / 5, buckets ); 222 240 free( buckets ); 223 241 } 224 ENDTIME( );242 ENDTIME( " x 5 " ); 225 243 226 244 sout | nl | "Concurrent"; … … 232 250 } // wait for threads to complete 233 251 } 234 ENDTIME( );252 ENDTIME( " x 5 " ); 235 253 #endif // 0 236 254 #if 1 … … 239 257 240 258 sout | sepDisable; 241 sout | nl | wd( 13, "prng(t)" ) | wd(10, "prng(t,5)") | wd(13, "prng(t,0,5)" );242 for ( 20 ) { 243 sout | wd( 13, prng( th )) | nonl; // cascading => side-effect functions called in arbitary order244 sout | wd(1 0, prng( th, 5 )) | nonl;245 sout | wd(1 3, prng( th, 0, 5 ));259 sout | nl | wd(26, "prng(t)" ) | wd(12, "prng(t,5)") | wd(12, "prng(t,0,5)" ); 260 for ( 20 ) { 261 sout | wd(26, prng( th )) | nonl; // cascading => side-effect functions called in arbitary order 262 sout | wd(12, prng( th, 5 )) | nonl; 263 sout | wd(12, prng( th, 0, 5 )); 246 264 } // for 247 265 sout | sepEnable; … … 266 284 #endif // 0 267 285 // malloc_stats(); 286 // freelocale( loc ); 268 287 } // main 269 288
Note:
See TracChangeset
for help on using the changeset viewer.