Generating the same random numbers with threads in OMP

前端 未结 2 1117
旧时难觅i
旧时难觅i 2021-01-15 10:04

I am attempting to multithread some code with OMP. Currently my sequentially version using rand() to generate a set of random numbers with a consistent seed so that they ret

2条回答
  •  萌比男神i
    2021-01-15 11:09

    Here is a block based approach that divides the problem space in N/BLOCK_SIZE blocks and reseeds the RNG with your randInit + block number for each block. This gives a reproducible output no matter the number of threads you have. It also generates the same initial N numbers for sequence of N + x. This as long as you keep the same BLOCK_SIZE.

    A good block-size is probably something like your typical N / (max_num_procs * 2). But there is room for experimentation.

    #include 
    #include 
    #include 
    
    #define N_DEFAULT  48   //Default number of nodes 
    #define BLOCK_SIZE 12   //BLOCK SIZE number of nodes per block.
                            //Changes this changes reseed frequencey, 
                            //.. and hence the generated sequence
    #define randInit   42   //Had to be something.
    
    int main(int argc , char* argv[])
    {
        int N=N_DEFAULT;
        if (argc >1)
            N=atoi(argv[1]); 
    
        int rands[N];// keep our random numbers for sequential debug output
        int n=BLOCK_SIZE;
        int num_blocks=(N+BLOCK_SIZE-1)/ BLOCK_SIZE;  // ceil(N/BLOCK_SIZE)
        int nt=omp_get_max_threads();   
    
    
        printf("          N: %d\n",N);
        printf("     Blocks: %d, (size: %d)\n",num_blocks,n);
        printf("    threads: %d\n",nt);
    
        //Parallel random generation
        #pragma omp parallel for schedule(runtime) 
        for (int J=0;J N?N:start+n;
    
            int tid = omp_get_thread_num(); // Just for debug
            printf("thread %d: works on block %d (%d - %d )\n",tid,J,start,end);
    
            for (int j=start; j < end;j++)
            {           
                int t=rand_r(&block_seed); //rand_r provides thread safe (re-entrant rand)
                rands[j]=t;
            }
        }
    
        //Output for debug single thread
        for (int j=0; j < N;j++)
        {
            printf("%d : %d \n",j,rands[j]);
        }   
        return 0;
    }
    

    Output with different N, and number of threads shown below.

    N: 24                                   N: 27
    Blocks: 3, (size: 8)                    Blocks: 4, (size: 8)
    threads: 4                              threads: 1
    -------------------------------------|-------------------------------
    thread 1: works on block 1 (8 - 16 )    thread 0: works on block 0 (0 - 8 )
    thread 2: works on block 2 (16 - 24 )   thread 0: works on block 1 (8 - 16 )
    thread 0: works on block 0 (0 - 8 )     thread 0: works on block 2 (16 - 24 )
                                            thread 0: works on block 3 (24 - 27 )
    -------------------------------------|-------------------------------
    0 : 681191333                           0 : 681191333
    1 : 928546885                           1 : 928546885
    2 : 1457394273                          2 : 1457394273
    3 : 941445650                           3 : 941445650
    4 : 2129613237                          4 : 2129613237
    5 : 1661015563                          5 : 1661015563
    6 : 2071432601                          6 : 2071432601
    7 : 222443696                           7 : 222443696
    8 : 1156886562                          8 : 1156886562
    9 : 398918689                           9 : 398918689
    10 : 170756699                         10 : 170756699
    11 : 703115845                         11 : 703115845
    12 : 1424182583                        12 : 1424182583
    13 : 1516198481                        13 : 1516198481
    14 : 1740837599                        14 : 1740837599
    15 : 1148851528                        15 : 1148851528
    16 : 1633630368                        16 : 1633630368
    17 : 2015727614                        17 : 2015727614
    18 : 1031602773                        18 : 1031602773
    19 : 463737465                         19 : 463737465
    20 : 720848057                         20 : 720848057
    21 : 1369285272                        21 : 1369285272
    22 : 1411290150                        22 : 1411290150
    23 : 2074210785                        23 : 2074210785
    -------------------------------------|-------------------------------
                                           24 : 2109326622
                                           25 : 1486099418
                                           26 : 1892448847
    

提交回复
热议问题