Multithreaded/Multiprocessing


PTHREADS


/* Ahl's simple benchmark */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <phtread.h>

typedef struct {
   int t;
   int *iter;
   int tnum;
} ahl_arg_t;


void ahl(ahl_arg_t *args)
{
  double r,s,a;
  int i,n;

  r=0; s=0;
  printf("..%d",args->tnum);
  fflush(stdout);
  while ((time(0)-args->t)<20) {
    (*(args->iter))++;
    r=0; s=0;
    for (n=1;n<=100;n++) {
      a = n;
      for (i=1;i<=10;i++) {
        a = sqrt(a); 
        r = r + ((double)random())/LONG_MAX;
      }
      for (i=1;i<=10;i++) {
        a = a*a; 
        r = r + ((double)random())/LONG_MAX;
      }
      s = s + a;
    }
  } 
  if (!args->tnum) {
    printf("\n%g\n",fabs(1010.-s/5.));
    printf("%f\n",fabs(1000.-r));
  }
}

int main(int argc,char *argv[])
{
  ahl_arg_t *arg_array;
  int *iters;
  pthread_t *threads;
  int nthreads;
  int i,t,total_iters=0;

#ifdef NEEDS_PTHREAD_INIT
  pthread_init();
#endif
  printf("ahlmt.c -- The POSIX multithreaded version of Ahl's simple benchmark\n"); 
  if (argc!=2) {
    printf("usage: ahlmt n_threads\n");
    exit(1);
  }

  sscanf(argv[1],"%d",&nthreads);
  if (!(arg_array=calloc(nthreads,sizeof(ahl_arg_t))) ||
      !(iters=calloc(nthreads,sizeof(int))) ||
      !(threads=calloc(nthreads,sizeof(pthread_t)))) {
    printf("insufficient memory\n");
    exit(1);
  }

  t=time(0);
  while (t==time(0));
  t=time(0);

  printf("thread");
  for (i=0;i<nthreads;i++) {
    arg_array[i].t=t;
    arg_array[i].iter=iters+i;
    arg_array[i].tnum=i;
    if (pthread_create(&threads[i],NULL,ahl,&arg_array[i])) {
      printf("thread creation failed for thread %d\n",i);
      exit(1);
    }
  }

  for (i=0;i<nthreads;i++) {
    pthread_join(threads[i],NULL);
    total_iters+=iters[i];
  }

  printf("%d iterations\n",total_iters);

  return(0);
}

Occam



#INCLUDE "hostio.inc"
#USE "hostio.lib"
#USE "dblmath.lib"
#USE "string.lib"
#USE "convert.lib"

PROC main(CHAN OF SP kbd,scn)
  VAL MaxNumThreads IS 1000(INT):
  VAL NumThreads IS 5(INT):
  [MaxNumThreads]REAL64 r,s,a,rand:
  [MaxNumThreads]INT iter:
  [MaxNumThreads]INT64 seed:
  INT t,t1,iters:
  BOOL Error:
  TIMER clock:

  SEQ
    so.write.nl(kbd,scn)
    so.write.string.nl(kbd,scn,"ahl.occ")
    rand[0], seed[0] := DRAN(seed[0])
    so.write.real64(kbd,scn,rand[0],3,3)
    so.write.nl(kbd,scn)
    so.write.int64(kbd,scn,seed[0],3)
    so.write.nl(kbd,scn)
    rand[0], seed[0] := DRAN(seed[0])
    so.write.real64(kbd,scn,rand[0],3,3)
    so.write.nl(kbd,scn)
    so.write.int64(kbd,scn,seed[0],3)
    so.write.nl(kbd,scn)
    iters, Error := 0, TRUE
    clock ? t 
    t1 := t
    WHILE t = t1 
      clock ? t1
    WHILE (t1 - t) < 312500(INT)
      SEQ
	PAR proc = 0 FOR NumThreads
          SEQ
            iter[proc], r[proc], s[proc] := iter[proc] + 1, 0.0(REAL64), 0.0(REAL64)
            SEQ n = 0 FOR 100  
              SEQ 
		a[proc] := (REAL64 ROUND(n))
                SEQ i = 0 FOR 10
		  SEQ
		    rand[proc], seed[proc] := DRAN(seed[proc])
                    a[proc], r[proc] := DPOWER(a[proc],0.5(REAL64)), r[proc] + rand[proc]
                SEQ i = 0 FOR 10
		  SEQ
		    rand[proc], seed[proc] := DRAN(seed[proc])
                    a[proc], r[proc] := DPOWER(a[proc],2.0(REAL64)), r[proc] + rand[proc]
                s[proc] := s[proc] + a[proc]
        clock ? t1
    SEQ proc = 0 FOR NumThreads
      iters := iters + iter[proc]

    so.write.int(kbd,scn,iters,4)
    so.write.string.nl(kbd,scn," iterations")
    so.write.real64(kbd,scn,(REAL64 ROUND(t1 - t))/(15625.0(REAL64)*(REAL64 ROUND(iters))),3,3)
    so.write.string(kbd,scn," seconds per iteration")
    so.write.nl(kbd,scn)
    so.write.real64(kbd,scn,DABS(1010.0(REAL64)-(s[0]/5.0(REAL64))),3,3)
    so.write.nl(kbd,scn)
    so.write.real64(kbd,scn,DABS(1000.0(REAL64)-r[0]),3,3)
    so.write.nl(kbd,scn)
    so.exit(kbd,scn,sps.success)
:

Unix Processes (fork)



/* Ahl's simple benchmark */
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

union semun {
  int val;
  struct semid_ds *buf;
  ushort *array;
} arg;


int main(int argc,char *argv[])
{
  double r,s,a;
  int i,n,iter=0;
  int t;
  int nforks;
  int proc_num;
  int fd[2];
  struct sembuf getsem,freesem;
  union semun arg;
  int semid;

  if (argc!=2) {
    printf("usage: ahlmp n_processes\n");
    exit(1);
  }

  if (pipe(fd)) {
    printf("pipe() failed\n");
    exit(1);
  }


  if ((semid=semget(IPC_PRIVATE,1,IPC_CREAT | 0700))==-1) {
    printf("semaphore creation failed\n");
    exit(1);
  }

  arg.val=1;
  if (semctl(semid,0,SETVAL,arg)) {
    printf("semaphore SETVAL error %d\n",errno);
    exit(1);
  }

  getsem.sem_num=0;
  getsem.sem_op=-1;
  getsem.sem_flg=0;

  freesem.sem_num=0;
  freesem.sem_op=1;
  freesem.sem_flg=0;

  printf("ahlmp.c -- The unix multiprocessing version of Ahl's simple benchmark\n");
  sscanf(argv[1],"%d",&nforks);
  printf("%d processes\n",nforks);
  printf("process"); 
  fflush(stdout);
  proc_num=nforks;
  srandom(time(0));
  t=time(0);
  while (t==time(0));
  t=time(0);
  while (proc_num--) {
    if (!fork()) {
      semop(semid,&getsem,1);
      printf("...%d",proc_num+1);
      fflush(stdout);
      semop(semid,&freesem,1);
      iter=0;
      r=0; s=0;
      while ((time(0)-t)<20) {
        iter++;
        r=0; s=0;
        for (n=1;n<=100;n++) {
          a = n;
          for (i=1;i<=10;i++) {
            a = sqrt(a); 
            r = r + ((double)random())/LONG_MAX;
          }
          for (i=1;i<=10;i++) {
            a = a*a; 
            r = r + ((double)random())/LONG_MAX;
          }
          s = s + a;
        }
      }
      semop(semid,&getsem,1);
      write(fd[1],&iter,sizeof(iter));
      if (proc_num==0) {
        printf("\n%g\n",fabs(1010.-s/5.));
        printf("%f\n",fabs(1000.-r));
      }
    semop(semid,&freesem,1);
    fflush(stdout);
    exit(0);
    } 
  } 
  close(fd[1]);
  while (read(fd[0],&iter,sizeof(iter))) {
    proc_num+=iter;
  }
  printf("%d iterations\n",proc_num);
  printf("%g seconds per iteration\n",20./proc_num);
  semctl(semid,0,IPC_RMID,arg);
  exit(0);
} 


Copyright © 2001 Eric Korpela
korpela@ssl.berkeley.edu