Révision 56 Pi/C/MPI/Pi_MPI.c
Pi_MPI.c (revision 56) | ||
---|---|---|
3 | 3 |
// gcc -std=c99 -O3 -o Pi Pi.c -lm |
4 | 4 |
// |
5 | 5 |
|
6 |
// Needed for gethostname |
|
7 |
#define _BSD_SOURCE |
|
8 |
#include <sys/unistd.h> |
|
9 |
|
|
6 | 10 |
#include <math.h> |
7 | 11 |
#include <stdio.h> |
8 | 12 |
#include <stdlib.h> |
... | ... | |
32 | 36 |
#define LENGTH int |
33 | 37 |
#endif |
34 | 38 |
|
39 |
unsigned int rotl(unsigned int value, int shift) { |
|
40 |
return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift)); |
|
41 |
} |
|
42 |
|
|
43 |
unsigned int rotr(unsigned int value, int shift) { |
|
44 |
return (value >> shift) | (value << (sizeof(value) * CHAR_BIT - shift)); |
|
45 |
} |
|
46 |
|
|
35 | 47 |
LENGTH MainLoopGlobal(LENGTH iterations,unsigned int seed_w,unsigned int seed_z) |
36 | 48 |
{ |
37 | 49 |
unsigned int z=seed_z; |
... | ... | |
55 | 67 |
|
56 | 68 |
int main(int argc, char *argv[]) { |
57 | 69 |
|
58 |
unsigned int seed_w=10,seed_z=10;
|
|
70 |
unsigned int seed_z=362436069,seed_w=52128862;
|
|
59 | 71 |
LENGTH iterations=ITERATIONS,inside[1024],insides,part_inside,part_iterations; |
60 | 72 |
int numtasks,rank,rc,tag=1,i; |
61 | 73 |
float pi; |
62 | 74 |
|
75 |
char hostname[128]; |
|
76 |
|
|
77 |
gethostname(hostname, sizeof hostname); |
|
78 |
|
|
63 | 79 |
#ifdef TIME |
64 | 80 |
struct timeval start,end; |
65 | 81 |
long int useconds; |
... | ... | |
77 | 93 |
MPI_Comm_rank(MPI_COMM_WORLD,&rank); |
78 | 94 |
|
79 | 95 |
if (rank==0) { |
80 |
|
|
96 |
|
|
81 | 97 |
if (argc > 1) { |
82 | 98 |
iterations=(LENGTH)atoll(argv[1]); |
83 | 99 |
} |
... | ... | |
85 | 101 |
printf("\n\tPi : Estimate Pi with Monte Carlo exploration\n\n"); |
86 | 102 |
printf("\t\t#1 : number of iterations (default 1 billion)\n\n"); |
87 | 103 |
} |
88 |
|
|
104 |
|
|
89 | 105 |
printf ("Sizeof int = %lld bytes.\n", (long long)sizeof(int)); |
90 | 106 |
printf ("Sizeof long = %lld bytes.\n", (long long)sizeof(long)); |
91 | 107 |
printf ("Sizeof long long = %lld bytes.\n", (long long)sizeof(long long)); |
92 |
|
|
108 |
|
|
93 | 109 |
printf ("Max int = %u\n", INT_MAX); |
94 | 110 |
printf ("Max long = %ld\n", LONG_MAX); |
95 | 111 |
printf ("Max long long = %lld\n", LLONG_MAX); |
96 |
|
|
112 |
|
|
97 | 113 |
part_iterations=iterations/numtasks+1; |
98 |
|
|
114 |
|
|
99 | 115 |
// Split part of code |
100 | 116 |
for (i=1;i<numtasks;i++) { |
101 |
|
|
117 |
|
|
102 | 118 |
#ifdef LONG |
103 | 119 |
rc = MPI_Send(&part_iterations, 1, MPI_LONG_LONG, i, tag, |
104 | 120 |
MPI_COMM_WORLD); |
... | ... | |
111 | 127 |
#ifdef TIME |
112 | 128 |
gettimeofday(&start,(struct timezone *)0); |
113 | 129 |
#endif |
114 |
|
|
130 |
|
|
115 | 131 |
insides=MainLoopGlobal(part_iterations,seed_w,seed_z); |
116 |
|
|
132 |
|
|
117 | 133 |
#ifdef TIME |
118 | 134 |
gettimeofday(&end,(struct timezone *)0); |
119 | 135 |
useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec; |
120 |
|
|
121 |
printf("\tOn %i, find %lld inside in %lu useconds.\n",rank,
|
|
122 |
(long long)insides,useconds); |
|
136 |
|
|
137 |
printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
|
|
138 |
hostname,rank,(long long)insides,useconds);
|
|
123 | 139 |
#else |
124 |
printf("\tOn %i, find %lld inside\n",rank,
|
|
140 |
printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
|
|
125 | 141 |
(long long)insides); |
126 |
|
|
142 |
|
|
127 | 143 |
#endif |
128 |
|
|
144 |
|
|
129 | 145 |
// Join part of code |
130 |
for (i=1;i<numtasks;i++) { |
|
146 |
for (i=1;i<numtasks;i++) {
|
|
131 | 147 |
#ifdef LONG |
132 |
rc = MPI_Recv(&inside[i], 1, MPI_LONG_LONG, i, tag,
|
|
133 |
MPI_COMM_WORLD, &Stat);
|
|
148 |
rc = MPI_Recv(&inside[i], 1, MPI_LONG_LONG, i, tag,
|
|
149 |
MPI_COMM_WORLD, &Stat);
|
|
134 | 150 |
#else |
135 |
rc = MPI_Recv(&inside[i], 1, MPI_INT, i, tag,
|
|
136 |
MPI_COMM_WORLD, &Stat);
|
|
151 |
rc = MPI_Recv(&inside[i], 1, MPI_INT, i, tag,
|
|
152 |
MPI_COMM_WORLD, &Stat);
|
|
137 | 153 |
#endif |
138 |
printf("\tReceive %lu inside from %i\n",(unsigned long)inside[i],i); |
|
139 |
insides+=inside[i]; |
|
140 |
} |
|
141 |
|
|
142 |
pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks); |
|
143 |
|
|
144 |
printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lld iterations\n\n",pi, |
|
145 |
fabs(pi-4*atan(1.))/pi,(long long)iterations); |
|
154 |
printf("\tReceive %lu inside from rank %i\n",(unsigned long)inside[i],i); |
|
155 |
insides+=inside[i]; |
|
156 |
} |
|
157 |
|
|
158 |
pi=4.*(float)insides/(float)((iterations/numtasks)*numtasks); |
|
159 |
|
|
160 |
printf("\n\tPi=%.40f\n\twith error %.40f\n\twith %lld iterations\n\n",pi, |
|
161 |
fabs(pi-4*atan(1.))/pi,(long long)iterations); |
|
162 |
|
|
146 | 163 |
} |
147 | 164 |
else |
148 | 165 |
{ |
... | ... | |
154 | 171 |
rc = MPI_Recv(&part_iterations, 1, MPI_INT, 0, tag, |
155 | 172 |
MPI_COMM_WORLD, &Stat); |
156 | 173 |
#endif |
157 |
|
|
158 |
printf("\tOn %i, receive from master %lld\n", |
|
159 |
rank,(long long)part_iterations); |
|
160 | 174 |
|
175 |
printf("\tOn %s with rank %i, receive from master %lld\n", |
|
176 |
hostname,rank,(long long)part_iterations); |
|
177 |
|
|
161 | 178 |
#ifdef TIME |
162 | 179 |
gettimeofday(&start,(struct timezone *)0); |
163 | 180 |
#endif |
164 | 181 |
|
165 |
part_inside=MainLoopGlobal(part_iterations,seed_w,seed_z);
|
|
182 |
part_inside=MainLoopGlobal(part_iterations,rotr(seed_w,rank),rotl(seed_z,rank));
|
|
166 | 183 |
|
184 |
|
|
167 | 185 |
#ifdef TIME |
168 |
gettimeofday(&end,(struct timezone *)0); |
|
169 |
useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec; |
|
170 |
|
|
171 |
printf("\tOn %i, find %lld inside in %lu useconds.\n",rank,
|
|
172 |
(long long)part_inside,useconds); |
|
186 |
gettimeofday(&end,(struct timezone *)0);
|
|
187 |
useconds=(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec;
|
|
188 |
|
|
189 |
printf("\tOn %s with rank %i, find %lld inside in %lu useconds.\n",
|
|
190 |
hostname,rank,(long long)part_inside,useconds);
|
|
173 | 191 |
#else |
174 |
printf("\tOn %i, find %lld inside\n",rank,
|
|
192 |
printf("\tOn %s with rank %i, find %lld inside\n",hostname,rank,
|
|
175 | 193 |
(long long)part_inside); |
176 |
|
|
194 |
|
|
177 | 195 |
#endif |
196 |
|
|
197 |
#ifdef LONG |
|
198 |
rc = MPI_Send(&part_inside, 1, MPI_LONG_LONG, 0, tag, MPI_COMM_WORLD); |
|
199 |
#else |
|
200 |
rc = MPI_Send(&part_inside, 1, MPI_INT, 0, tag, MPI_COMM_WORLD); |
|
201 |
#endif |
|
178 | 202 |
|
179 |
rc = MPI_Send(&part_inside, 1, MPI_UNSIGNED_LONG, 0, tag, MPI_COMM_WORLD); |
|
180 | 203 |
} |
181 | 204 |
|
182 | 205 |
MPI_Finalize(); |
183 |
|
|
206 |
|
|
184 | 207 |
} |
Formats disponibles : Unified diff