tags:

views:

96

answers:

2

I wrote this code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/shm.h>

#define   N  512

void  chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void  chunk1(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void  chunk2(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void  chunk3(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
double get_time(void);

void  main(void)
{
    int i,j,k,iterations=0;
    int plc=N/4;
    unsigned int *a=(unsigned int *)malloc(N*N*(sizeof(unsigned int)));
    unsigned int *b=(unsigned int *)malloc(N*N*(sizeof(unsigned int)));
    unsigned int shmsz=N*N*(sizeof(unsigned int));
    pid_t  pid;

    srand ( time(NULL) );
    double start=get_time();

    int shmid;
    if ((shmid = shmget(IPC_PRIVATE, shmsz, IPC_CREAT | 0666)) < 0) {
        perror("shmget");
        exit(1);
    }
    //Now we attach the segment to our data space.
    char *shm;
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }   
    unsigned int *s = (unsigned int *) shm;

    for(iterations=0;iterations<1000;iterations++){
        printf("Iteration #%d\n",iterations+1);
        for(i=0;i<N;i++){
            for(j=0;j<N;j++){
                *(a+(i*N+j))=(rand()%1001);
                *(b+(i*N+j))=(rand()%1001);;
                *(s+(i*N+j))=0;
            }
        }

        pid = fork();
        if (pid == 0) {
             chunk0(s,a,b,plc,iterations);
             break;
        }else {
            pid = fork();
            if (pid == 0){ 
                 chunk1(s,a,b,plc,iterations);
                 break;
            }else {
                pid = fork();
                if (pid == 0){ 
                     chunk2(s,a,b,plc,iterations);
                     break;
                }else {
                    chunk3(s,a,b,plc,iterations);
                    wait(NULL);
                }
            }
        }
        wait(NULL);
    }

    double end=get_time();
    double diff=end-start;
    printf("\n Time for run this code is: %lf seconds \n",diff);

}

void  chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
    int i,j,k;

    for(i=0;i<MID;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }   
        }
    }
    printf("\tChild process 0 (Iteration %d) is done ***\n",it);
    exit(0);
}
void  chunk1(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
    int i,j,k;

    for(i=MID;i<MID*2;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }
        }
    }
     printf("\tChild process 1 (Iteration %d) is done ***\n",it);
     exit(0);
}
void  chunk2(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
    int i,j,k;

    for(i=MID*2;i<MID*3;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }
        }
    }

     printf("\tChild process 2 (Iteration %d) is done ***\n",it);
     exit(0);
}
void  chunk3(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
     int i,j,k;

    for(i=MID*3;i<N;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }
        }
    }

     printf("\tChild process 3 (Iteration %d) is done ***\n",it);
//     exit(0);
}

double get_time(void){
    struct timeval stime;
    gettimeofday (&stime, (struct timezone*)0);
    return (stime.tv_sec+((double)stime.tv_usec)/1000000);
}  

Program doesn't wait until one iteration be complete and starts next iteration!
look at results:

Iteration #1
    Child process 0 (Iteration 0) is done ***
    Child process 3 (Iteration 0) is done ***
    Child process 1 (Iteration 0) is done ***
Iteration #2
    Child process 2 (Iteration 0) is done ***
    Child process 0 (Iteration 1) is done ***
    Child process 1 (Iteration 1) is done ***
    Child process 3 (Iteration 1) is done ***
Iteration #3
    Child process 2 (Iteration 1) is done ***
    Child process 0 (Iteration 2) is done ***
    Child process 3 (Iteration 2) is done ***
Iteration #4
    Child process 1 (Iteration 2) is done ***
    Child process 2 (Iteration 2) is done ***
    Child process 1 (Iteration 3) is done ***
    Child process 3 (Iteration 3) is done ***
Iteration #5
    Child process 0 (Iteration 3) is done ***
    Child process 2 (Iteration 3) is done ***
    Child process 0 (Iteration 4) is done ***
    Child process 1 (Iteration 4) is done ***
    Child process 2 (Iteration 4) is done ***
    Child process 3 (Iteration 4) is done ***
Iteration #6
    Child process 1 (Iteration 5) is done ***
    Child process 0 (Iteration 5) is done ***
    Child process 2 (Iteration 5) is done ***
    Child process 3 (Iteration 5) is done ***
Iteration #7
    Child process 0 (Iteration 6) is done ***
    Child process 1 (Iteration 6) is done ***
    Child process 2 (Iteration 6) is done ***
    Child process 3 (Iteration 6) is done ***

What about this?
I used wait(NULL) but ...

+3  A: 

wait() will only wait until a single child process exits. You want to wait until they all have exited. I think you simply need to call it 3 times in a row...

R..
Worked ! Thank you very much
Snigger
+1  A: 

You are not properly waiting for your created child processes. You should do it like this:

pid = fork();
if (pid == 0) {
    chunk0(s,a,b,plc,iterations);
    break;
}else {
    pid = fork();
    if (pid == 0){ 
        chunk1(s,a,b,plc,iterations);
        break;
    }else {
        pid = fork();
        if (pid == 0){ 
            chunk2(s,a,b,plc,iterations);
            break;
        }else {
            chunk3(s,a,b,plc,iterations);
            wait(NULL);
        }
        wait(NULL);
    }
    wait(NULL);
}

It looks rather awful, and you should rethink your program logic to make it more readable. Also, remember to properly cleanup your resources from the child processes before exiting (see shmdt).

Another thing to consider is using shm_open and shm_unlink instead.

the_void