Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (4,82 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
#include <limits.h>
17

    
18
#define NUM_THREADS        1024
19

    
20
#define ITERATIONS 1000000000
21

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

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

    
37
struct thread_data thread_data_array[NUM_THREADS];
38

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

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

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

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

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

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

    
126
  printf ("Sizeof int = %d bytes.\n", sizeof(int));
127
  printf ("Sizeof long = %d bytes.\n", sizeof(long));
128
  printf ("Sizeof long long = %d bytes.\n", sizeof(long long));
129

    
130
  printf ("Max int = %u\n", INT_MAX);
131
  printf ("Max long = %ld\n", LONG_MAX);
132
  printf ("Max long long = %lld\n", LLONG_MAX);
133

    
134
  printf("\tNumber of threads defined to %u\n",num_threads);
135
  printf("\tNumber of iterations defined to %lld\n\n",(long long)iterations);
136

    
137
  /* Initialize and set thread detached attribute */
138
  pthread_attr_init(&attr);
139
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
140

    
141
  for(t=0;t<num_threads;t++) {
142
    
143
    thread_data_array[t].thread_id = t;
144
    thread_data_array[t].iterations = iterations/(long long)num_threads;
145
    thread_data_array[t].seed_w = (t+1)<<4;
146
    thread_data_array[t].seed_z = (1048576*(t+1))>>4;
147
    thread_data_array[t].inside = 0;
148
    
149
    printf("\tCreating thread %d\n", t);
150
    rc = pthread_create(&threads[t], &attr, MainLoopThread, (void *) 
151
                        &thread_data_array[t]);
152

    
153
    if (rc) {
154
      printf("\tERROR; return code from pthread_create() is %d\n", rc);
155
      exit(-1);
156
    }
157
  }
158
  
159
  /* Free attribute and wait for the other threads */
160
  pthread_attr_destroy(&attr);
161

    
162
  for(t=0; t<num_threads; t++) {
163
    rc = pthread_join(threads[t], &status);
164
    if (rc) {
165
      printf("\tERROR; return code from pthread_join() is %d\n", rc);
166
      exit(-1);
167
    }
168
    printf("\tMain: completed join with thread %i having a status of %ld\n",
169
           t,(long)status);
170
  }
171

    
172
  for(t=0;t<num_threads;t++) {
173
    printf("\tReturn to main with %i thread, %lld inside\n", 
174
           t,(long long)thread_data_array[t].inside);
175
    inside+=thread_data_array[t].inside;
176
  }
177

    
178
  printf("\tMain: program completed. Exiting.\n\n");
179

    
180
  pi=4.*(float)inside/(float)iterations;
181

    
182
  printf("\tPi=%f with error %f and %lld iterations\n\n",pi,
183
         fabs(pi-4*atan(1))/pi,(long long)iterations);
184

    
185
  pthread_exit(NULL);
186
}