Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • tests/PRNG.cfa

    r4246869 r20cf96d  
    1 //
     1//                               -*- Mode: C -*-
     2//
    23// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
    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 //
     4//
     5// PRNG.c --
     6//
    97// Author           : Peter A. Buhr
    108// Created On       : Wed Dec 29 09:38:12 2021
    119// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 25 15:39:52 2023
    13 // Update Count     : 422
     10// Last Modified On : Tue Nov 22 22:51:12 2022
     11// Update Count     : 381
    1412//
    1513
     
    1715#include <stdlib.hfa>                                                                   // PRNG
    1816#include <clock.hfa>
     17#include <thread.hfa>
    1918#include <limits.hfa>                                                                   // MAX
    2019#include <math.hfa>                                                                             // sqrt
    2120#include <malloc.h>                                                                             // malloc_stats
    2221#include <locale.h>                                                                             // setlocale
    23 #include <thread.hfa>
    2422#include <mutex_stmt.hfa>
    2523
    26 #define xstr(s) str(s)
    27 #define str(s) #s
    28 
    29 #if defined( __x86_64__ ) || defined( __aarch64__ )             // 64-bit architecture
     24#ifdef __x86_64__                                                                               // 64-bit architecture
    3025#define PRNG PRNG64
    3126#else                                                                                                   // 32-bit architecture
    3227#define PRNG PRNG32
    3328#endif // __x86_64__
    34 
    35 //#define TIME
    3629
    3730#ifdef TIME                                                                                             // use -O2 -nodebug
     
    4538#endif // TIME
    4639
    47 static void avgstd( size_t trials, size_t buckets[] ) {
    48         size_t min = MAX, max = 0;
     40void avgstd( unsigned int buckets[] ) {
     41        unsigned int min = MAX, max = 0;
    4942        double sum = 0.0, diff;
    5043        for ( i; BUCKETS ) {
     
    6154        } // for
    6255        double std = sqrt( sum / BUCKETS );
    63         mutex( sout ) sout | "trials"  | trials | "buckets" | BUCKETS
     56        mutex( sout ) sout | "trials"  | TRIALS | "buckets" | BUCKETS
    6457                | "min" | min | "max" | max
    6558                | "avg" | wd(0,1, avg) | "std" | wd(0,1, std) | "rstd" | wd(0,1, (avg == 0 ? 0.0 : std / avg * 100)) | "%";
     
    6760
    6861
    69 size_t seed = 1009;
     62unsigned int seed = 1009;
    7063
    7164thread T1 {};
    7265void main( T1 & ) {
    73         size_t * buckets = calloc( BUCKETS );                           // too big for task stack
    74         for ( TRIALS / 50 ) {
     66        unsigned int * buckets = calloc( BUCKETS );                     // too big for task stack
     67        for ( TRIALS / 100 ) {
    7568                buckets[rand() % BUCKETS] += 1;                                 // concurrent
    7669        } // for
    77         avgstd( TRIALS / 50, buckets );
     70        avgstd( buckets );
    7871        free( buckets );
    7972} // main
     
    8376        PRNG prng;
    8477        if ( seed != 0 ) set_seed( prng, seed );
    85         size_t * buckets = calloc( BUCKETS );                           // too big for task stack
     78        unsigned int * buckets = calloc( BUCKETS );                     // too big for task stack
    8679        for ( TRIALS ) {
    8780                buckets[prng( prng ) % BUCKETS] += 1;                   // concurrent
    8881        } // for
    89         avgstd( TRIALS, buckets );
     82        avgstd( buckets );
    9083        free( buckets );
    9184} // main
     
    9386thread T3 {};
    9487void main( T3 & th ) {
    95         size_t * buckets = calloc( BUCKETS );                           // too big for task stack
    96         for ( TRIALS / 5 ) {
     88        unsigned int * buckets = calloc( BUCKETS );                     // too big for task stack
     89        for ( TRIALS ) {
    9790                buckets[prng() % BUCKETS] += 1;                                 // concurrent
    9891        } // for
    99         avgstd( TRIALS / 5, buckets );
     92        avgstd( buckets );
    10093        free( buckets );
    10194} // main
     
    10396thread T4 {};
    10497void main( T4 & th ) {
    105         size_t * buckets = calloc( BUCKETS );                           // too big for task stack
     98        unsigned int * buckets = calloc( BUCKETS );                     // too big for task stack
    10699        for ( TRIALS ) {
    107                 buckets[prng( th ) % BUCKETS] += 1;                             // concurrent
    108         } // for
    109         avgstd( TRIALS, buckets );
     100                buckets[prng( th ) % BUCKETS] += 1;     // concurrent
     101        } // for
     102        avgstd( buckets );
    110103        free( buckets );
    111104} // main
     
    115108static void dummy( thread$ & th ) __attribute__(( noinline ));
    116109static void dummy( thread$ & th ) {
    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 ) {
     110        unsigned int * buckets = (unsigned int *)calloc( BUCKETS, sizeof(unsigned int) ); // too big for task stack
     111        for ( unsigned int i = 0; i < TRIALS; i += 1 ) {
    119112                buckets[prng( th ) % BUCKETS] += 1;                             // sequential
    120113        } // for
    121         avgstd( TRIALS, buckets );
     114        avgstd( buckets );
    122115        free( buckets );
    123116} // dummy
    124117
    125 
    126118int main() {
    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 );
     119        // causes leaked storage message
     120//      setlocale( LC_NUMERIC, getenv( "LANG" ) );                      // print digit separator
    133121
    134122        enum { TASKS = 4 };
    135123        Time start;
    136 
    137124#ifdef TIME                                                                                             // too slow for test and generates non-repeatable results
    138125#if 1
    139         sout | "glib rand" | nl | nl;
    140 
    141         size_t rseed;
     126        unsigned int rseed;
    142127        if ( seed != 0 ) rseed = seed;
    143128        else rseed = rdtscl();
     
    145130
    146131        sout | sepDisable;
    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);
     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(10, rand() % 5) | nonl;
     136                sout | wd(13, rand() % (5 - 0 + 1) + 0);
    152137        } // for
    153138        sout | sepEnable;
     
    157142        STARTTIME;
    158143        {
    159                 size_t * buckets = calloc( BUCKETS );                   // too big for task stack
    160                 for ( i; TRIALS / 5 ) {
     144                unsigned int * buckets = calloc( BUCKETS );             // too big for task stack
     145                for ( i; TRIALS / 10 ) {
    161146                        buckets[rand() % BUCKETS] += 1;                         // sequential
    162147                } // for
    163                 avgstd( TRIALS / 5, buckets );
     148                avgstd( buckets );
    164149                free( buckets );
    165150        }
    166         ENDTIME( " x 5 " );
     151        ENDTIME( " x 10 " );
    167152
    168153        sout | nl | "Concurrent";
     
    174159                } // wait for threads to complete
    175160        }
    176         ENDTIME( " x 50 " );
     161        ENDTIME( " x 100 " );
    177162#endif // 0
    178163#endif // TIME
    179 
    180         sout | nl | "CFA " xstr(PRNG_NAME);
    181 
    182164#if 1
    183165        PRNG prng;
     
    186168
    187169        sout | sepDisable;
    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 ));
     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 order
     173                sout | wd(10, prng( prng, 5 )) | nonl;
     174                sout | wd(13, prng( prng, 0, 5 ));
    193175        } // for
    194176        sout | sepEnable;
     
    198180        STARTTIME;
    199181        {
    200                 size_t * buckets = calloc( BUCKETS );                   // too big for task stack
     182                unsigned int * buckets = calloc( BUCKETS );             // too big for task stack
    201183                for ( TRIALS ) {
    202184                        buckets[prng( prng ) % BUCKETS] += 1;           // sequential
    203185                } // for
    204                 avgstd( TRIALS, buckets );
     186                avgstd( buckets );
    205187                free( buckets );
    206188        }
     
    221203
    222204        sout | sepDisable;
    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 ));
     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 order
     208                sout | wd(10, prng( 5 )) | nonl;
     209                sout | wd(13, prng( 0, 5 ));
    228210        } // for
    229211        sout | sepEnable;
     
    233215        STARTTIME;
    234216        {
    235                 size_t * buckets = calloc( BUCKETS );                   // too big for task stack
    236                 for ( TRIALS / 5 ) {
     217                unsigned int * buckets = calloc( BUCKETS );             // too big for task stack
     218                for ( TRIALS ) {
    237219                        buckets[prng() % BUCKETS] += 1;
    238220                } // for
    239                 avgstd( TRIALS / 5, buckets );
     221                avgstd( buckets );
    240222                free( buckets );
    241223        }
    242         ENDTIME( " x 5 " );
     224        ENDTIME();
    243225
    244226        sout | nl | "Concurrent";
     
    250232                } // wait for threads to complete
    251233        }
    252         ENDTIME( " x 5 " );
     234        ENDTIME();
    253235#endif // 0
    254236#if 1
     
    257239
    258240        sout | sepDisable;
    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 ));
     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 order
     244                sout | wd(10, prng( th, 5 )) | nonl;
     245                sout | wd(13, prng( th, 0, 5 ));
    264246        } // for
    265247        sout | sepEnable;
     
    284266#endif // 0
    285267//      malloc_stats();
    286         // freelocale( loc );
    287268} // main
    288269
Note: See TracChangeset for help on using the changeset viewer.