Multithreaded/Multiprocessing
/* 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);
}
#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)
:
/* 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