1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
/* parallel computation of pi with monte carlo method */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int rdtsc()
{
__asm__ __volatile__("rdtsc");
}
double* Parallel( double* smem, pid_t* pid, int nbt, long int niter, int statut, int options, int nb_current )
{
double x,y,z;
long int i;
int j;
srand(rdtsc());
if (nbt==1)
{ smem[nb_current]=0;
for (i=0; i<(niter/nbt); i++)
{ x = (double) rand() / RAND_MAX;
y = (double) rand() / RAND_MAX;
z = x*x + y*y;
if (z <= 1.0)
{smem[nb_current]++;}}
return smem;
}
else if (nb_current==nbt) return smem;
else { pid[nb_current]=fork();
if (pid[nb_current]<0) {exit(4);}
else if (pid[nb_current]==0)
{ smem=Parallel(smem,pid,nbt,niter,statut,options,nb_current+2);
// child process
// compute the niter/nbt part of niter hits
smem[nb_current] = 0;
for (i=0; i<(niter/nbt); i++)
{ x = (double) rand() / RAND_MAX;
y = (double) rand() / RAND_MAX;
z = x*x + y*y;
if (z <= 1.0) {smem[nb_current]++; }
}
printf("------smem in child-----nb_current=%d ---\n",nb_current);
for(j=0;j<nbt;j++)
{printf("smem[%d]=%f\n",j,smem[j]);}
exit(0);
}
else
{ // parent process
// compute the niter/nbt part of niter hits
smem[nb_current+1] = 0;
for (i=0; i<(niter/nbt); i++)
{ x = (double) rand() / RAND_MAX;
y = (double) rand() / RAND_MAX;
z = x*x + y*y;
if (z <= 1.0) {smem[nb_current+1]++; }
}
waitpid(pid[nb_current],&statut,options);
printf("------smem in parent-----nb_current+1=%d ---\n",nb_current+1);
for(j=0;j<nbt;j++)
{printf("smem[%d]=%f\n",j,smem[j]);}
return smem;
}
}
}
int main (int argc, char** argv)
{ long int niter; // total number of hits
long int fd;long int i;
int shm_id;
int nb_process; // number of threads
int nb_current=0; // current index in Parallel recursive function
double x,y,z;
double pi=0;
// struct sharedMem* smem;
double* smem;
struct timeval chrono1, chrono2;
int micro, second; pid_t *pid;
int pseudo_pid;
int statut;
int options = 0;
// parse the argument
if (argc != 3)
{ printf ("Please, specify number of threads and iterations \n");
exit (1); }
nb_process = atoi(argv[1]);
niter = atol(argv[2]);
// create the shared memory
fd = open ("/tmp/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1) exit(2);
if (ftruncate (fd, nb_process*sizeof (double)) == -1) exit(3);
smem = mmap (NULL, nb_process*sizeof (double),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (smem == MAP_FAILED) exit(1);
// initialize pid
pid=(pid_t*)malloc(nb_process*sizeof(pid_t));
// initialize time process
gettimeofday(&chrono1, NULL);
// monte carlo's method in parallel
smem=Parallel(smem,pid,nb_process,niter,statut,options,nb_current);
gettimeofday(&chrono2, NULL);
close(fd);
// compute ellapsed time
micro = chrono2.tv_usec - chrono1.tv_usec;
if (micro < 0)
{ micro += 1000000;
second = chrono2.tv_sec - chrono1.tv_sec - 1; }
else
second = chrono2.tv_sec - chrono1.tv_sec;
//printf("-------------------------\n");
for(i=0;i<nb_process;i++)
{//printf("smem[%d]=%f\n",i,smem[i]);
pi = pi+ smem[i];}
pi= pi/niter;
pi *= 4;
// Output
printf("# of trials= %ld , estimate of pi is %1.8f \n",niter,pi);
printf("%d second %d micro ellapsed\n", second, micro);
/* Don't forget to free the mmapped memory
*/
if (munmap(smem, nb_process*sizeof (double)) == -1) {
printf("Error un-mmapping the file\n");
/* Decide here whether to close(fd) and exit() or not. Depends... */
}
/* Un-mmaping doesn't close the file, so we still need to do that.
*/
close(fd);
return 0;
} |
Partager