Statistiques
| Révision :

root / Pi / C / Pthreads / Pi_Pthreads.c @ 23

Historique | Voir | Annoter | Télécharger (4,51 ko)

1
/******************************************************************************
2
* FILE: Pi_Threads
3
* Pthreads based on Hello from Blaise Barney, LLNL Tutorial
4
* DESCRIPTION:
5
*   A Pi by Monte Carlo Pthreads program.  Demonstrates thread creation and
6
*   termination.
7
* AUTHOR: Emmanuel Quemener from Blaise Barney
8
* LAST REVISED: 2013-03-30
9
******************************************************************************/
10

    
11
#include <pthread.h>
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <math.h>
15
#include <stdio.h>
16

    
17
#define NUM_THREADS        1024
18

    
19
#define ITERATIONS 1000000000
20

    
21
#ifdef LONG
22
#define LENGTH unsigned long
23
#else
24
#define LENGTH unsigned int
25
#endif
26

    
27
struct thread_data
28
{
29
  int thread_id;
30
  unsigned int seed_w;
31
  unsigned int seed_z;
32
  LENGTH iterations;
33
  LENGTH inside;
34
};
35

    
36
struct thread_data thread_data_array[NUM_THREADS];
37

    
38
// Marsaglia RNG very simple implementation
39
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
40
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
41
#define MWC   (znew+wnew)
42
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
43
#define CONG  (jcong=69069*jcong+1234567)
44
#define KISS  ((MWC^CONG)+SHR3)
45

    
46
#define MWCfp MWC * 2.328306435454494e-10f
47
#define KISSfp KISS * 2.328306435454494e-10f
48

    
49
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
50
{
51
  unsigned int z=seed_z;
52
  unsigned int w=seed_w;
53
  
54
  LENGTH total=0;
55
  
56
  for (LENGTH i=0;i<iterations;i++) {
57
    
58
    float x=MWCfp ;
59
    float y=MWCfp ;
60
    
61
    // Matching test
62
    LENGTH inside=((x*x+y*y) < 1.0f) ? 1:0;
63
    total+=inside;
64
   }
65
  
66
  return(total);
67
  
68
}
69

    
70
void *MainLoopThread(void *threadarg)
71
{
72
  int taskid;
73
  LENGTH iterations,total=0;
74
  unsigned int z,w;
75
  
76
  struct thread_data *my_data;
77
  
78
  my_data=(struct thread_data *) threadarg;
79
  
80
  taskid = my_data->thread_id;
81
  iterations = my_data->iterations;
82
  z = my_data->seed_z;
83
  w = my_data->seed_w;
84

    
85
  printf("\tThread #%i, with seeds (%u,%u) and %lu !\n",
86
         taskid,z,w,(unsigned long)iterations);
87
  
88
  for (LENGTH i=0;i<iterations;i++) {
89
    
90
    float x=MWCfp ;
91
    float y=MWCfp ;
92
    
93
    // Matching test
94
    LENGTH inside=((x*x+y*y) < 1.0f) ? 1:0;
95
    total+=inside;
96
  }
97
  
98
  my_data->inside=total;
99
  
100
  pthread_exit((void*) my_data);
101
}
102

    
103
int main(int argc, char *argv[])
104
{
105
  pthread_t threads[NUM_THREADS];
106
  pthread_attr_t attr;
107
  int rc, t;
108
  unsigned int num_threads;
109
  LENGTH iterations,inside=0;
110
  void *status;
111
  float pi;
112
  
113
  if (argc > 1) {
114
    iterations=(LENGTH)atol(argv[1]);
115
    num_threads=atoi(argv[2]);
116
  }
117
  else {
118
    iterations=ITERATIONS;
119
    num_threads=1;
120
    printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n");
121
    printf("\t\t#1 : number of iterations (default 1 billion)\n");
122
    printf("\t\t#2 : number of threads (default 1)\n\n");
123
  }
124
  
125
  printf("\tNumber of threads defined to %u\n",num_threads);
126
  printf("\tNumber of iterations defined to %lu\n\n",(unsigned long)iterations);
127

    
128
  /* Initialize and set thread detached attribute */
129
  pthread_attr_init(&attr);
130
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
131

    
132
  for(t=0;t<num_threads;t++) {
133
    
134
    thread_data_array[t].thread_id = t;
135
    thread_data_array[t].iterations = iterations/num_threads;
136
    thread_data_array[t].seed_w = (t+1)<<4;
137
    thread_data_array[t].seed_z = (1048576*(t+1))>>4;
138
    thread_data_array[t].inside = 0;
139
    
140
    printf("\tCreating thread %d\n", t);
141
    rc = pthread_create(&threads[t], &attr, MainLoopThread, (void *) 
142
                        &thread_data_array[t]);
143

    
144
    if (rc) {
145
      printf("\tERROR; return code from pthread_create() is %d\n", rc);
146
      exit(-1);
147
    }
148
  }
149
  
150
  /* Free attribute and wait for the other threads */
151
  pthread_attr_destroy(&attr);
152

    
153
  for(t=0; t<num_threads; t++) {
154
    rc = pthread_join(threads[t], &status);
155
    if (rc) {
156
      printf("\tERROR; return code from pthread_join() is %d\n", rc);
157
      exit(-1);
158
    }
159
    printf("\tMain: completed join with thread %i having a status of %ld\n",
160
           t,(long)status);
161
  }
162

    
163
  for(t=0;t<num_threads;t++) {
164
    printf("\tReturn to main with %i thread, %lu inside\n", 
165
           t,(unsigned long)thread_data_array[t].inside);
166
    inside+=thread_data_array[t].inside;
167
  }
168

    
169
  printf("\tMain: program completed. Exiting.\n\n");
170

    
171
  pi=4.*(float)inside/(float)iterations;
172

    
173
  printf("\tPi=%f with error %f and %lu iterations\n\n",pi,
174
         fabs(pi-4*atan(1))/pi,(unsigned long)iterations);
175

    
176
  pthread_exit(NULL);
177
}