Statistiques
| Révision :

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

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