Statistiques
| Révision :

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

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

1 12 equemene
/******************************************************************************
2 12 equemene
* FILE: Pi_Threads
3 12 equemene
* Pthreads based on Hello from Blaise Barney, LLNL Tutorial
4 12 equemene
* DESCRIPTION:
5 12 equemene
*   A Pi by Monte Carlo Pthreads program.  Demonstrates thread creation and
6 12 equemene
*   termination.
7 12 equemene
* AUTHOR: Emmanuel Quemener from Blaise Barney
8 12 equemene
* LAST REVISED: 2013-03-30
9 12 equemene
******************************************************************************/
10 12 equemene
11 12 equemene
#include <pthread.h>
12 12 equemene
#include <stdio.h>
13 12 equemene
#include <stdlib.h>
14 12 equemene
#include <math.h>
15 12 equemene
#include <stdio.h>
16 12 equemene
17 12 equemene
#define NUM_THREADS        1024
18 12 equemene
19 12 equemene
#define ITERATIONS 1000000000
20 12 equemene
21 12 equemene
#ifdef LONG
22 12 equemene
#define LENGTH unsigned long
23 12 equemene
#else
24 12 equemene
#define LENGTH unsigned int
25 12 equemene
#endif
26 12 equemene
27 12 equemene
struct thread_data
28 12 equemene
{
29 12 equemene
  int thread_id;
30 12 equemene
  unsigned int seed_w;
31 12 equemene
  unsigned int seed_z;
32 12 equemene
  LENGTH iterations;
33 12 equemene
  LENGTH inside;
34 12 equemene
};
35 12 equemene
36 12 equemene
struct thread_data thread_data_array[NUM_THREADS];
37 12 equemene
38 12 equemene
// Marsaglia RNG very simple implementation
39 12 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
40 12 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
41 12 equemene
#define MWC   (znew+wnew)
42 12 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
43 12 equemene
#define CONG  (jcong=69069*jcong+1234567)
44 12 equemene
#define KISS  ((MWC^CONG)+SHR3)
45 12 equemene
46 12 equemene
#define MWCfp MWC * 2.328306435454494e-10f
47 12 equemene
#define KISSfp KISS * 2.328306435454494e-10f
48 12 equemene
49 12 equemene
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z)
50 12 equemene
{
51 12 equemene
  unsigned int z=seed_z;
52 12 equemene
  unsigned int w=seed_w;
53 12 equemene
54 12 equemene
  LENGTH total=0;
55 12 equemene
56 12 equemene
  for (LENGTH i=0;i<iterations;i++) {
57 12 equemene
58 12 equemene
    float x=MWCfp ;
59 12 equemene
    float y=MWCfp ;
60 12 equemene
61 12 equemene
    // Matching test
62 12 equemene
    LENGTH inside=((x*x+y*y) < 1.0f) ? 1:0;
63 12 equemene
    total+=inside;
64 12 equemene
   }
65 12 equemene
66 12 equemene
  return(total);
67 12 equemene
68 12 equemene
}
69 12 equemene
70 12 equemene
void *MainLoopThread(void *threadarg)
71 12 equemene
{
72 12 equemene
  int taskid;
73 12 equemene
  LENGTH iterations,total=0;
74 12 equemene
  unsigned int z,w;
75 12 equemene
76 12 equemene
  struct thread_data *my_data;
77 12 equemene
78 12 equemene
  my_data=(struct thread_data *) threadarg;
79 12 equemene
80 12 equemene
  taskid = my_data->thread_id;
81 12 equemene
  iterations = my_data->iterations;
82 12 equemene
  z = my_data->seed_z;
83 12 equemene
  w = my_data->seed_w;
84 12 equemene
85 12 equemene
  printf("\tThread #%i, with seeds (%u,%u) and %lu !\n",
86 12 equemene
         taskid,z,w,(unsigned long)iterations);
87 12 equemene
88 12 equemene
  for (LENGTH i=0;i<iterations;i++) {
89 12 equemene
90 12 equemene
    float x=MWCfp ;
91 12 equemene
    float y=MWCfp ;
92 12 equemene
93 12 equemene
    // Matching test
94 12 equemene
    LENGTH inside=((x*x+y*y) < 1.0f) ? 1:0;
95 12 equemene
    total+=inside;
96 12 equemene
  }
97 12 equemene
98 12 equemene
  my_data->inside=total;
99 12 equemene
100 12 equemene
  pthread_exit((void*) my_data);
101 12 equemene
}
102 12 equemene
103 12 equemene
int main(int argc, char *argv[])
104 12 equemene
{
105 12 equemene
  pthread_t threads[NUM_THREADS];
106 12 equemene
  pthread_attr_t attr;
107 12 equemene
  int rc, t;
108 12 equemene
  unsigned int num_threads;
109 12 equemene
  LENGTH iterations,inside=0;
110 12 equemene
  void *status;
111 12 equemene
  float pi;
112 12 equemene
113 12 equemene
  if (argc > 1) {
114 12 equemene
    iterations=(LENGTH)atol(argv[1]);
115 12 equemene
    num_threads=atoi(argv[2]);
116 12 equemene
  }
117 12 equemene
  else {
118 12 equemene
    iterations=ITERATIONS;
119 12 equemene
    num_threads=1;
120 12 equemene
    printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n");
121 12 equemene
    printf("\t\t#1 : number of iterations (default 1 billion)\n");
122 12 equemene
    printf("\t\t#2 : number of threads (default 1)\n\n");
123 12 equemene
  }
124 12 equemene
125 12 equemene
  printf("\tNumber of threads defined to %u\n",num_threads);
126 12 equemene
  printf("\tNumber of iterations defined to %lu\n\n",(unsigned long)iterations);
127 12 equemene
128 12 equemene
  /* Initialize and set thread detached attribute */
129 12 equemene
  pthread_attr_init(&attr);
130 12 equemene
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
131 12 equemene
132 12 equemene
  for(t=0;t<num_threads;t++) {
133 12 equemene
134 12 equemene
    thread_data_array[t].thread_id = t;
135 12 equemene
    thread_data_array[t].iterations = iterations/num_threads;
136 12 equemene
    thread_data_array[t].seed_w = (t+1)<<4;
137 12 equemene
    thread_data_array[t].seed_z = (1048576*(t+1))>>4;
138 12 equemene
    thread_data_array[t].inside = 0;
139 12 equemene
140 12 equemene
    printf("\tCreating thread %d\n", t);
141 12 equemene
    rc = pthread_create(&threads[t], &attr, MainLoopThread, (void *)
142 12 equemene
                        &thread_data_array[t]);
143 12 equemene
144 12 equemene
    if (rc) {
145 12 equemene
      printf("\tERROR; return code from pthread_create() is %d\n", rc);
146 12 equemene
      exit(-1);
147 12 equemene
    }
148 12 equemene
  }
149 12 equemene
150 12 equemene
  /* Free attribute and wait for the other threads */
151 12 equemene
  pthread_attr_destroy(&attr);
152 12 equemene
153 12 equemene
  for(t=0; t<num_threads; t++) {
154 12 equemene
    rc = pthread_join(threads[t], &status);
155 12 equemene
    if (rc) {
156 12 equemene
      printf("\tERROR; return code from pthread_join() is %d\n", rc);
157 12 equemene
      exit(-1);
158 12 equemene
    }
159 12 equemene
    printf("\tMain: completed join with thread %i having a status of %ld\n",
160 12 equemene
           t,(long)status);
161 12 equemene
  }
162 12 equemene
163 12 equemene
  for(t=0;t<num_threads;t++) {
164 12 equemene
    printf("\tReturn to main with %i thread, %lu inside\n",
165 12 equemene
           t,(unsigned long)thread_data_array[t].inside);
166 12 equemene
    inside+=thread_data_array[t].inside;
167 12 equemene
  }
168 12 equemene
169 12 equemene
  printf("\tMain: program completed. Exiting.\n\n");
170 12 equemene
171 12 equemene
  pi=4.*(float)inside/(float)iterations;
172 12 equemene
173 12 equemene
  printf("\tPi=%f with error %f and %lu iterations\n\n",pi,
174 12 equemene
         fabs(pi-4*atan(1))/pi,(unsigned long)iterations);
175 12 equemene
176 12 equemene
  pthread_exit(NULL);
177 12 equemene
}